1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-09 20:12:21 +02:00

Added System.Compiler compile-time values

This commit is contained in:
Brian Fiete 2020-09-04 08:09:04 -07:00
parent 24aaa22f7a
commit 25f44ae133
11 changed files with 294 additions and 75 deletions

View file

@ -0,0 +1,29 @@
namespace System
{
static class Compiler
{
[LinkName("#CallerLineNum")]
public static extern int CallerLineNum;
[LinkName("#CallerFilePath")]
public static extern String CallerFilePath;
[LinkName("#CallerFileName")]
public static extern String CallerFileName;
[LinkName("#CallerFileDir")]
public static extern String CallerFileDir;
[LinkName("#CallerMemberName")]
public static extern String CallerMemberName;
[LinkName("#CallerProject")]
public static extern String CallerProject;
[LinkName("#CallerExpression")]
public static extern String[Int32.MaxValue] CallerExpression;
[LinkName("#TimeLocal")]
public static extern String TimeLocal;
}
}

View file

@ -5,27 +5,22 @@ namespace System.Diagnostics
#if !DEBUG
[SkipCall]
#endif
public static void Assert(bool condition)
public static void Assert(bool condition, String error = Compiler.CallerExpression[0], String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
{
if (!condition)
Internal.FatalError("Assert failed", 1);
{
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
Internal.FatalError(failStr, 1);
}
}
#if !DEBUG
[SkipCall]
#endif
public static void Assert(bool condition, String error)
public static void FatalError(String msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
{
if (!condition)
Internal.FatalError(error, 1);
}
#if !DEBUG
[SkipCall]
#endif
public static void FatalError(String msg = "Fatal error encountered")
{
Internal.FatalError(msg, 1);
String failStr = scope .()..AppendF("{} at line {} in {}", msg, line, filePath);
Internal.FatalError(failStr, 1);
}
#if !DEBUG

View file

@ -306,27 +306,26 @@ namespace System
}
[NoReturn]
public static void FatalError(String msg = "Fatal error encountered")
public static void FatalError(String msg = "Fatal error encountered", String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
{
Internal.FatalError(msg, 1);
String failStr = scope .()..AppendF("{} at line {} in {}", msg, line, filePath);
Internal.FatalError(failStr, 1);
}
[NoReturn]
public static void NotImplemented()
public static void NotImplemented(String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
{
Internal.FatalError("Not Implemented", 1);
String failStr = scope .()..AppendF("Not Implemented at line {} in {}", line, filePath);
Internal.FatalError(failStr, 1);
}
public static void Assert(bool condition)
public static void Assert(bool condition, String error = Compiler.CallerExpression[0], String filePath = Compiler.CallerFilePath, int line = Compiler.CallerLineNum)
{
if (!condition)
Internal.FatalError("Assert failed", 1);
}
public static void Assert(bool condition, String error)
{
if (!condition)
Internal.FatalError(error, 1);
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
Internal.FatalError(failStr, 1);
}
}
}
}

View file

@ -4129,7 +4129,7 @@ void BfCompiler::ProcessAutocompleteTempType()
if ((fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL))
{
auto customAttrs = module->GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, BfAttributeTargets_Field);
auto customAttrs = module->GetCustomAttributes(fieldDef->mFieldDeclaration->mAttributes, fieldDef->mIsStatic ? BfAttributeTargets_StaticField : BfAttributeTargets_Field);
delete customAttrs;
}

View file

@ -89,9 +89,8 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
if (wantType != NULL)
mExpectingType = wantType;
VisitChildNoRef(expr);
mResult = GetResult();
if (mResult)
mResult = mModule->LoadValue(mResult);
if ((mResult) && (wantType != NULL))
{
auto typeInst = mResult.mType->ToTypeInstance();
@ -114,8 +113,8 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
else
{
int stringId = mModule->GetStringPoolIdx(mResult.mValue);
BF_ASSERT(stringId >= 0);
if (stringId != -1)
{
if ((flags & BfConstResolveFlag_RemapFromStringId) != 0)
{
ignoreWrites.Restore();
@ -127,6 +126,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
}
}
}
}
if (noCast)
{
@ -180,7 +180,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
if (isConst)
{
auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
if (constant->mConstType == BfConstType_GlobalVar)
if ((constant->mConstType == BfConstType_GlobalVar) && ((mBfEvalExprFlags & BfConstResolveFlag_AllowGlobalVariable) != 0))
isConst = false;
}

View file

@ -16,7 +16,8 @@ enum BfConstResolveFlags
BfConstResolveFlag_NoCast = 2,
BfConstResolveFlag_AllowSoftFail = 4,
BfConstResolveFlag_RemapFromStringId = 8,
BfConstResolveFlag_ArrayInitSize = 0x10
BfConstResolveFlag_ArrayInitSize = 0x10,
BfConstResolveFlag_AllowGlobalVariable = 0x20,
};
class BfConstResolver : public BfExprEvaluator

View file

@ -21,6 +21,7 @@
#include "BfFixits.h"
#pragma warning(pop)
#pragma warning(disable:4996)
#include "BeefySysLib/util/AllocDebug.h"
@ -5840,6 +5841,88 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
argValue = mModule->GetDefaultTypedValue(wantType, false, BfDefaultValueKind_Addr);
}
}
else if (foreignConst->mConstType == BfConstType_GlobalVar)
{
auto globalVar = (BfGlobalVar*)foreignConst;
if (globalVar->mName[0] == '#')
{
if (strcmp(globalVar->mName, "#CallerLineNum") == 0)
{
argValue = BfTypedValue(mModule->GetConstValue(mModule->mCurFilePosition.mCurLine + 1), mModule->GetPrimitiveType(BfTypeCode_Int32));
}
else if (strcmp(globalVar->mName, "#CallerFilePath") == 0)
{
String filePath = "";
if (mModule->mCurFilePosition.mFileInstance != NULL)
filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
argValue = BfTypedValue(mModule->GetStringObjectValue(filePath),
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
}
else if (strcmp(globalVar->mName, "#CallerFileName") == 0)
{
String filePath = "";
if (mModule->mCurFilePosition.mFileInstance != NULL)
filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileName(filePath)),
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
}
else if (strcmp(globalVar->mName, "#CallerFileDir") == 0)
{
String filePath = "";
if (mModule->mCurFilePosition.mFileInstance != NULL)
filePath = mModule->mCurFilePosition.mFileInstance->mParser->mFileName;
argValue = BfTypedValue(mModule->GetStringObjectValue(GetFileDir(filePath)),
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
}
else if (strcmp(globalVar->mName, "#CallerMemberName") == 0)
{
String memberName = "";
if (mModule->mCurMethodInstance != NULL)
memberName = mModule->MethodToString(mModule->mCurMethodInstance);
argValue = BfTypedValue(mModule->GetStringObjectValue(memberName),
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
}
else if (strcmp(globalVar->mName, "#CallerProject") == 0)
{
String projectName = "";
if (mModule->mCurMethodInstance != NULL)
projectName = mModule->mCurMethodInstance->mMethodDef->mDeclaringType->mProject->mName;
argValue = BfTypedValue(mModule->GetStringObjectValue(projectName),
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
}
else
{
argValue = mModule->GetCompilerFieldValue(globalVar->mName);
}
}
}
else if (foreignConst->mConstType == BfConstType_GEP32_2)
{
auto constGep32_2 = (BfConstantGEP32_2*)foreignConst;
auto gepTarget = methodInstance->GetOwner()->mConstHolder->GetConstantById(constGep32_2->mTarget);
if (gepTarget->mConstType == BfConstType_GlobalVar)
{
auto globalVar = (BfGlobalVar*)gepTarget;
if (globalVar->mName[0] == '#')
{
if (strcmp(globalVar->mName, "#CallerExpression") == 0)
{
int exprIdx = constGep32_2->mIdx1;
if ((exprIdx >= 0) && (exprIdx <= (int)argValues.size()))
{
argValue = BfTypedValue(mModule->GetStringObjectValue(argValues[exprIdx].mExpression->ToString()),
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
}
else
{
mModule->Fail("CallerExpression index out of bounds", targetSrc);
argValue = BfTypedValue(mModule->GetStringObjectValue(""),
mModule->ResolveTypeDef(mModule->mCompiler->mStringTypeDef));
}
}
}
}
}
if (!argValue)
{
@ -17516,9 +17599,12 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
{
if (target.mType->IsSizeAligned())
{
auto ptrType = mModule->CreatePointerType(underlyingType);
auto ptrValue = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType));
auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(ptrValue, indexArgument.mValue);
// auto ptrType = mModule->CreatePointerType(underlyingType);
// auto ptrValue = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType));
// auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(ptrValue, indexArgument.mValue);
// mResult = BfTypedValue(gepResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(target.mValue, mModule->GetConstValue(0), indexArgument.mValue);
mResult = BfTypedValue(gepResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
}
else
@ -18941,15 +19027,21 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
if ((binaryOp == BfBinaryOp_StrictEquality) || (binaryOp == BfBinaryOp_StrictInEquality))
skipOpOverload = true;
else if (BfBinOpEqualityCheck(binaryOp))
{
if (!leftValue.IsAddr())
{
auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
if ((leftConstant != NULL) && (leftConstant->IsNull()))
skipOpOverload = true;
}
if (!rightValue.IsAddr())
{
auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
if ((rightConstant != NULL) && (rightConstant->IsNull()))
skipOpOverload = true;
}
}
if (!skipOpOverload)
{

View file

@ -2675,10 +2675,13 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
if (!staticVarName.StartsWith("#"))
{
String fieldName = DbgGetStaticFieldName(fieldInstance);
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
constDIType, false, staticValue, memberType);
}
}
else if (resolvedFieldType->IsValuelessType())
{
// Do nothing
@ -2788,17 +2791,20 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
resolvedFieldDIType, flags, BfIRValue());
diFieldTypes.push_back(memberType);
StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
if (!staticVarName.StartsWith('#'))
{
auto staticValue = mModule->ReferenceStaticField(fieldInstance);
if (staticValue.mValue)
{
StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
String fieldName = DbgGetStaticFieldName(fieldInstance);
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
resolvedFieldDIType, false, staticValue.mValue, memberType);
}
}
}
}
else
{
bool useForUnion = false;
@ -4101,6 +4107,15 @@ BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, BfIRValue idx0)
BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, BfIRValue idx0, BfIRValue idx1)
{
if ((val.IsConst()) && (idx0.IsConst()) && (idx1.IsConst()))
{
auto idx0Constant = GetConstant(idx0);
auto idx1Constant = GetConstant(idx1);
if ((IsInt(idx0Constant->mTypeCode)) && (IsInt(idx1Constant->mTypeCode)))
return CreateInBoundsGEP(val, idx0Constant->mInt32, idx1Constant->mInt32);
}
BfIRValue retVal = WriteCmd(BfIRCmd_InBoundsGEP2, val, idx0, idx1);
NEW_CMD_INSERTED_IRVALUE;
return retVal;

View file

@ -2244,6 +2244,35 @@ void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstan
void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance)
{
if (fieldInstance->mCustomAttributes != NULL)
{
auto module = fieldInstance->mOwner->mModule;
auto linkNameAttr = fieldInstance->mCustomAttributes->Get(module->mCompiler->mLinkNameAttributeTypeDef);
if (linkNameAttr != NULL)
{
if (linkNameAttr->mCtorArgs.size() == 1)
{
if (module->TryGetConstString(fieldInstance->mOwner->mConstHolder, linkNameAttr->mCtorArgs[0], outStr))
if (!outStr.IsWhitespace())
return;
auto constant = fieldInstance->mOwner->mConstHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
if (constant != NULL)
{
if (constant->mInt32 == 1) // C
{
outStr += fieldInstance->GetFieldDef()->mName;
return;
}
else if (constant->mInt32 == 2) // CPP
{
//mangleContext.mCPPMangle = true;
}
}
}
}
}
if (mangleKind == BfMangler::MangleKind_GNU)
outStr += BfGNUMangler::MangleStaticFieldName(fieldInstance->mOwner, fieldInstance->GetFieldDef()->mName);
else

View file

@ -2,8 +2,8 @@
#include "BeefySysLib/util/AllocDebug.h"
#pragma warning(push) // 6
#pragma warning(disable:4996)
#pragma warning(push) // 6
#include "BfCompiler.h"
#include "BfSystem.h"
@ -1097,7 +1097,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
// code as we walk the AST
//mBfIRBuilder->mDbgVerifyCodeGen = true;
if (
(mModuleName == "-")
(mModuleName == "BeefTest_TestProgram")
//|| (mModuleName == "BeefTest2_ClearColorValue")
//|| (mModuleName == "Tests_FuncRefs")
)
@ -3381,6 +3381,7 @@ BfCheckedKind BfModule::GetDefaultCheckedKind()
void BfModule::AddFailType(BfTypeInstance* typeInstance)
{
BF_ASSERT(typeInstance != NULL);
mContext->mFailTypes.Add(typeInstance);
}
@ -3454,7 +3455,7 @@ void BfModule::CreateStaticField(BfFieldInstance* fieldInstance, bool isThreadLo
BfLogSysM("Creating static field Module:%p Type:%p\n", this, fieldType);
StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), fieldInstance);
if (!fieldType->IsValuelessType())
if ((!fieldType->IsValuelessType()) && (!staticVarName.StartsWith("#")))
{
BfIRValue globalVar = mBfIRBuilder->CreateGlobalVariable(
mBfIRBuilder->MapType(fieldType, BfIRPopulateType_Eventually_Full),
@ -3538,11 +3539,13 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
{
if (!fieldDef->mTypeRef->IsA<BfPointerTypeRef>())
{
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
Fail("Extern consts must be pointer types", fieldDef->mFieldDeclaration->mTypeRef);
}
if (fieldDef->mInitializer != NULL)
{
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
Fail("Extern consts cannot have initializers", fieldDef->mFieldDeclaration->mNameNode);
}
}
@ -10058,11 +10061,19 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst
break;
default: break;
}
BfIRValue irValue = ConstantToCurrent(constant, constHolder, wantType);
BF_ASSERT(irValue);
if (!irValue)
return BfTypedValue();
if (constant->mConstType == BfConstType_GlobalVar)
{
auto result = BfTypedValue(irValue, wantType, true);
if (!wantType->IsComposite())
result = LoadValue(result);
return result;
}
return BfTypedValue(irValue, wantType, false);
}
@ -10839,6 +10850,25 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo
if ((typedValue.mType->IsValuelessType()) || (typedValue.mType->IsVar()))
return BfTypedValue(mBfIRBuilder->GetFakeVal(), typedValue.mType, false);
if (typedValue.mValue.IsConst())
{
auto constantValue = mBfIRBuilder->GetConstant(typedValue.mValue);
if (constantValue != NULL)
{
if (constantValue->mConstType == BfConstType_GlobalVar)
{
auto globalVar = (BfGlobalVar*)constantValue;
if (globalVar->mName[0] == '#')
{
BfTypedValue result = GetCompilerFieldValue(globalVar->mName);
if (result)
return result;
return GetDefaultTypedValue(typedValue.mType);
}
}
}
}
BfIRValue loadedVal = typedValue.mValue;
if (loadedVal)
{
@ -12603,14 +12633,28 @@ void BfModule::HadSlotCountDependency()
mUsedSlotCount = BF_MAX(mCompiler->mMaxInterfaceSlots, 0);
}
BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str)
{
if (mIsScratchModule)
if (str == "#TimeLocal")
{
// Just fake it for the extern and unspecialized modules
return BfTypedValue(mBfIRBuilder->GetFakeVal(), fieldInstance->GetResolvedType(), true);
time_t rawtime;
time(&rawtime);
tm* timeinfo = localtime(&rawtime);
char result[32];
sprintf(result, "%d/%.2d/%.2d %.2d:%.2d:%.2d",
1900 + timeinfo->tm_year,
timeinfo->tm_mon,
timeinfo->tm_mday,
timeinfo->tm_hour,
timeinfo->tm_min,
timeinfo->tm_sec);
return BfTypedValue(GetStringObjectValue(result), ResolveTypeDef(mCompiler->mStringTypeDef));
}
return BfTypedValue();
}
BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
{
BfIRValue globalValue;
auto fieldDef = fieldInstance->GetFieldDef();
@ -12628,6 +12672,12 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
}
}
if (mIsScratchModule)
{
// Just fake it for the extern and unspecialized modules
return BfTypedValue(mBfIRBuilder->CreateConstNull(), fieldInstance->GetResolvedType(), true);
}
BfIRValue* globalValuePtr = NULL;
if (mStaticFieldRefs.TryGetValue(fieldInstance, &globalValuePtr))
{
@ -12648,8 +12698,12 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
PopulateType(typeType);
if ((typeType != NULL) && (!typeType->IsValuelessType()))
{
BfIRType irType = mBfIRBuilder->MapType(typeType);
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mBfIRBuilder->mIgnoreWrites || staticVarName.StartsWith('#'));
globalValue = mBfIRBuilder->CreateGlobalVariable(
mBfIRBuilder->MapType(typeType),
irType,
false,
BfIRLinkageType_External,
BfIRValue(),
@ -16601,6 +16655,10 @@ void BfModule::EmitGCMarkMembers()
if ((fieldDef->mIsStatic) && (!fieldDef->mIsConst))
{
StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), &fieldInst);
if (staticVarName.StartsWith('#'))
continue;
markVal = ReferenceStaticField(&fieldInst);
}
else if (!fieldDef->mIsStatic)
@ -20368,7 +20426,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
else
{
BfConstResolver constResolver(this);
defaultValue = constResolver.Resolve(paramDef->mParamDeclaration->mInitializer, resolvedParamType, BfConstResolveFlag_NoCast);
defaultValue = constResolver.Resolve(paramDef->mParamDeclaration->mInitializer, resolvedParamType, (BfConstResolveFlags)(BfConstResolveFlag_NoCast | BfConstResolveFlag_AllowGlobalVariable));
if ((defaultValue) && (defaultValue.mType != resolvedParamType))
{
SetAndRestoreValue<bool> prevIgnoreWrite(mBfIRBuilder->mIgnoreWrites, true);

View file

@ -1548,6 +1548,7 @@ public:
bool CheckModifyValue(BfTypedValue& typedValue, BfAstNode* refNode, const char* modifyType = NULL);
BfIRValue GetInterfaceSlotNum(BfTypeInstance* ifaceType);
void HadSlotCountDependency();
BfTypedValue GetCompilerFieldValue(const StringImpl& str);
BfTypedValue ReferenceStaticField(BfFieldInstance* fieldInstance);
BfTypedValue GetThis();
BfLocalVariable* GetThisVariable();