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 #if !DEBUG
[SkipCall] [SkipCall]
#endif #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);
}
#if !DEBUG
[SkipCall]
#endif
public static void Assert(bool condition, String error)
{ {
if (!condition) if (!condition)
Internal.FatalError(error, 1); {
String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
Internal.FatalError(failStr, 1);
}
} }
#if !DEBUG #if !DEBUG
[SkipCall] [SkipCall]
#endif #endif
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);
} }
#if !DEBUG #if !DEBUG

View file

@ -306,27 +306,26 @@ namespace System
} }
[NoReturn] [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] [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) if (!condition)
Internal.FatalError("Assert failed", 1); {
} String failStr = scope .()..AppendF("Assert failed: {} at line {} in {}", error, line, filePath);
Internal.FatalError(failStr, 1);
public static void Assert(bool condition, String error) }
{
if (!condition)
Internal.FatalError(error, 1);
} }
} }
} }

View file

@ -4129,7 +4129,7 @@ void BfCompiler::ProcessAutocompleteTempType()
if ((fieldDef->mFieldDeclaration != NULL) && (fieldDef->mFieldDeclaration->mAttributes != NULL)) 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; delete customAttrs;
} }

View file

@ -89,9 +89,8 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
if (wantType != NULL) if (wantType != NULL)
mExpectingType = wantType; mExpectingType = wantType;
VisitChildNoRef(expr); VisitChildNoRef(expr);
mResult = GetResult(); mResult = GetResult();
if (mResult)
mResult = mModule->LoadValue(mResult);
if ((mResult) && (wantType != NULL)) if ((mResult) && (wantType != NULL))
{ {
auto typeInst = mResult.mType->ToTypeInstance(); auto typeInst = mResult.mType->ToTypeInstance();
@ -113,17 +112,18 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
} }
else else
{ {
int stringId = mModule->GetStringPoolIdx(mResult.mValue); int stringId = mModule->GetStringPoolIdx(mResult.mValue);
BF_ASSERT(stringId >= 0); if (stringId != -1)
if ((flags & BfConstResolveFlag_RemapFromStringId) != 0)
{ {
ignoreWrites.Restore(); if ((flags & BfConstResolveFlag_RemapFromStringId) != 0)
mModule->mBfIRBuilder->PopulateType(mResult.mType); {
return BfTypedValue(mModule->GetStringObjectValue(stringId), mResult.mType); ignoreWrites.Restore();
} mModule->mBfIRBuilder->PopulateType(mResult.mType);
return BfTypedValue(mModule->GetStringObjectValue(stringId), mResult.mType);
}
return BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId), toType); return BfTypedValue(mModule->mBfIRBuilder->CreateConst(BfTypeCode_StringId, stringId), toType);
}
} }
} }
} }
@ -180,10 +180,10 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo
if (isConst) if (isConst)
{ {
auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue); auto constant = mModule->mBfIRBuilder->GetConstant(mResult.mValue);
if (constant->mConstType == BfConstType_GlobalVar) if ((constant->mConstType == BfConstType_GlobalVar) && ((mBfEvalExprFlags & BfConstResolveFlag_AllowGlobalVariable) != 0))
isConst = false; isConst = false;
} }
if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0)) if ((!isConst) && ((mBfEvalExprFlags & BfEvalExprFlags_AllowNonConst) == 0))
{ {
mModule->Fail("Expression does not evaluate to a constant value", expr); mModule->Fail("Expression does not evaluate to a constant value", expr);

View file

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

View file

@ -21,6 +21,7 @@
#include "BfFixits.h" #include "BfFixits.h"
#pragma warning(pop) #pragma warning(pop)
#pragma warning(disable:4996)
#include "BeefySysLib/util/AllocDebug.h" #include "BeefySysLib/util/AllocDebug.h"
@ -5840,6 +5841,88 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
argValue = mModule->GetDefaultTypedValue(wantType, false, BfDefaultValueKind_Addr); 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) if (!argValue)
{ {
@ -17516,9 +17599,12 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
{ {
if (target.mType->IsSizeAligned()) if (target.mType->IsSizeAligned())
{ {
auto ptrType = mModule->CreatePointerType(underlyingType); // auto ptrType = mModule->CreatePointerType(underlyingType);
auto ptrValue = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType)); // auto ptrValue = mModule->mBfIRBuilder->CreateBitCast(target.mValue, mModule->mBfIRBuilder->MapType(ptrType));
auto gepResult = mModule->mBfIRBuilder->CreateInBoundsGEP(ptrValue, indexArgument.mValue); // 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); mResult = BfTypedValue(gepResult, underlyingType, target.IsReadOnly() ? BfTypedValueKind_ReadOnlyAddr : BfTypedValueKind_Addr);
} }
else else
@ -18942,13 +19028,19 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
skipOpOverload = true; skipOpOverload = true;
else if (BfBinOpEqualityCheck(binaryOp)) else if (BfBinOpEqualityCheck(binaryOp))
{ {
auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue); if (!leftValue.IsAddr())
auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue); {
auto leftConstant = mModule->mBfIRBuilder->GetConstant(leftValue.mValue);
if ((leftConstant != NULL) && (leftConstant->IsNull()))
skipOpOverload = true;
}
if ((leftConstant != NULL) && (leftConstant->IsNull())) if (!rightValue.IsAddr())
skipOpOverload = true; {
if ((rightConstant != NULL) && (rightConstant->IsNull())) auto rightConstant = mModule->mBfIRBuilder->GetConstant(rightValue.mValue);
skipOpOverload = true; if ((rightConstant != NULL) && (rightConstant->IsNull()))
skipOpOverload = true;
}
} }
if (!skipOpOverload) if (!skipOpOverload)

View file

@ -2675,9 +2675,12 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
StringT<128> staticVarName; StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance); BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
String fieldName = DbgGetStaticFieldName(fieldInstance); if (!staticVarName.StartsWith("#"))
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0, {
constDIType, false, staticValue, memberType); String fieldName = DbgGetStaticFieldName(fieldInstance);
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
constDIType, false, staticValue, memberType);
}
} }
else if (resolvedFieldType->IsValuelessType()) else if (resolvedFieldType->IsValuelessType())
{ {
@ -2788,14 +2791,17 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
resolvedFieldDIType, flags, BfIRValue()); resolvedFieldDIType, flags, BfIRValue());
diFieldTypes.push_back(memberType); diFieldTypes.push_back(memberType);
auto staticValue = mModule->ReferenceStaticField(fieldInstance); StringT<128> staticVarName;
if (staticValue.mValue) BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance);
if (!staticVarName.StartsWith('#'))
{ {
StringT<128> staticVarName; auto staticValue = mModule->ReferenceStaticField(fieldInstance);
BfMangler::Mangle(staticVarName, mModule->mCompiler->GetMangleKind(), fieldInstance); if (staticValue.mValue)
String fieldName = DbgGetStaticFieldName(fieldInstance); {
DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0, String fieldName = DbgGetStaticFieldName(fieldInstance);
resolvedFieldDIType, false, staticValue.mValue, memberType); DbgCreateGlobalVariable(diForwardDecl, fieldName, staticVarName, fileDIScope, 0,
resolvedFieldDIType, false, staticValue.mValue, memberType);
}
} }
} }
} }
@ -4101,6 +4107,15 @@ BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, BfIRValue idx0)
BfIRValue BfIRBuilder::CreateInBoundsGEP(BfIRValue val, BfIRValue idx0, BfIRValue idx1) 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); BfIRValue retVal = WriteCmd(BfIRCmd_InBoundsGEP2, val, idx0, idx1);
NEW_CMD_INSERTED_IRVALUE; NEW_CMD_INSERTED_IRVALUE;
return retVal; return retVal;

View file

@ -2243,7 +2243,36 @@ void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfMethodInstan
} }
void BfMangler::Mangle(StringImpl& outStr, MangleKind mangleKind, BfFieldInstance* fieldInstance) 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) if (mangleKind == BfMangler::MangleKind_GNU)
outStr += BfGNUMangler::MangleStaticFieldName(fieldInstance->mOwner, fieldInstance->GetFieldDef()->mName); outStr += BfGNUMangler::MangleStaticFieldName(fieldInstance->mOwner, fieldInstance->GetFieldDef()->mName);
else else

View file

@ -2,8 +2,8 @@
#include "BeefySysLib/util/AllocDebug.h" #include "BeefySysLib/util/AllocDebug.h"
#pragma warning(push) // 6
#pragma warning(disable:4996) #pragma warning(disable:4996)
#pragma warning(push) // 6
#include "BfCompiler.h" #include "BfCompiler.h"
#include "BfSystem.h" #include "BfSystem.h"
@ -1097,7 +1097,7 @@ void BfModule::EnsureIRBuilder(bool dbgVerifyCodeGen)
// code as we walk the AST // code as we walk the AST
//mBfIRBuilder->mDbgVerifyCodeGen = true; //mBfIRBuilder->mDbgVerifyCodeGen = true;
if ( if (
(mModuleName == "-") (mModuleName == "BeefTest_TestProgram")
//|| (mModuleName == "BeefTest2_ClearColorValue") //|| (mModuleName == "BeefTest2_ClearColorValue")
//|| (mModuleName == "Tests_FuncRefs") //|| (mModuleName == "Tests_FuncRefs")
) )
@ -3381,6 +3381,7 @@ BfCheckedKind BfModule::GetDefaultCheckedKind()
void BfModule::AddFailType(BfTypeInstance* typeInstance) void BfModule::AddFailType(BfTypeInstance* typeInstance)
{ {
BF_ASSERT(typeInstance != NULL);
mContext->mFailTypes.Add(typeInstance); 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); BfLogSysM("Creating static field Module:%p Type:%p\n", this, fieldType);
StringT<128> staticVarName; StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), fieldInstance); BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), fieldInstance);
if (!fieldType->IsValuelessType()) if ((!fieldType->IsValuelessType()) && (!staticVarName.StartsWith("#")))
{ {
BfIRValue globalVar = mBfIRBuilder->CreateGlobalVariable( BfIRValue globalVar = mBfIRBuilder->CreateGlobalVariable(
mBfIRBuilder->MapType(fieldType, BfIRPopulateType_Eventually_Full), mBfIRBuilder->MapType(fieldType, BfIRPopulateType_Eventually_Full),
@ -3538,11 +3539,13 @@ void BfModule::ResolveConstField(BfTypeInstance* typeInstance, BfFieldInstance*
{ {
if (!fieldDef->mTypeRef->IsA<BfPointerTypeRef>()) if (!fieldDef->mTypeRef->IsA<BfPointerTypeRef>())
{ {
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
Fail("Extern consts must be pointer types", fieldDef->mFieldDeclaration->mTypeRef); Fail("Extern consts must be pointer types", fieldDef->mFieldDeclaration->mTypeRef);
} }
if (fieldDef->mInitializer != NULL) if (fieldDef->mInitializer != NULL)
{ {
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mCurTypeInstance, typeInstance);
Fail("Extern consts cannot have initializers", fieldDef->mFieldDeclaration->mNameNode); Fail("Extern consts cannot have initializers", fieldDef->mFieldDeclaration->mNameNode);
} }
} }
@ -9995,7 +9998,7 @@ void BfModule::ClearConstData()
} }
BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType) BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType)
{ {
switch (constant->mTypeCode) switch (constant->mTypeCode)
{ {
case BfTypeCode_StringId: case BfTypeCode_StringId:
@ -10057,12 +10060,20 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst
} }
break; break;
default: break; default: break;
} }
BfIRValue irValue = ConstantToCurrent(constant, constHolder, wantType); BfIRValue irValue = ConstantToCurrent(constant, constHolder, wantType);
BF_ASSERT(irValue); BF_ASSERT(irValue);
if (!irValue) if (!irValue)
return BfTypedValue(); 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); return BfTypedValue(irValue, wantType, false);
} }
@ -10839,6 +10850,25 @@ BfTypedValue BfModule::LoadValue(BfTypedValue typedValue, BfAstNode* refNode, bo
if ((typedValue.mType->IsValuelessType()) || (typedValue.mType->IsVar())) if ((typedValue.mType->IsValuelessType()) || (typedValue.mType->IsVar()))
return BfTypedValue(mBfIRBuilder->GetFakeVal(), typedValue.mType, false); 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; BfIRValue loadedVal = typedValue.mValue;
if (loadedVal) if (loadedVal)
{ {
@ -12603,14 +12633,28 @@ void BfModule::HadSlotCountDependency()
mUsedSlotCount = BF_MAX(mCompiler->mMaxInterfaceSlots, 0); mUsedSlotCount = BF_MAX(mCompiler->mMaxInterfaceSlots, 0);
} }
BfTypedValue BfModule::GetCompilerFieldValue(const StringImpl& str)
{
if (str == "#TimeLocal")
{
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) BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
{ {
if (mIsScratchModule)
{
// Just fake it for the extern and unspecialized modules
return BfTypedValue(mBfIRBuilder->GetFakeVal(), fieldInstance->GetResolvedType(), true);
}
BfIRValue globalValue; BfIRValue globalValue;
auto fieldDef = fieldInstance->GetFieldDef(); auto fieldDef = fieldInstance->GetFieldDef();
@ -12626,7 +12670,13 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
{ {
return GetDefaultTypedValue(fieldInstance->GetResolvedType()); return GetDefaultTypedValue(fieldInstance->GetResolvedType());
} }
} }
if (mIsScratchModule)
{
// Just fake it for the extern and unspecialized modules
return BfTypedValue(mBfIRBuilder->CreateConstNull(), fieldInstance->GetResolvedType(), true);
}
BfIRValue* globalValuePtr = NULL; BfIRValue* globalValuePtr = NULL;
if (mStaticFieldRefs.TryGetValue(fieldInstance, &globalValuePtr)) if (mStaticFieldRefs.TryGetValue(fieldInstance, &globalValuePtr))
@ -12648,8 +12698,12 @@ BfTypedValue BfModule::ReferenceStaticField(BfFieldInstance* fieldInstance)
PopulateType(typeType); PopulateType(typeType);
if ((typeType != NULL) && (!typeType->IsValuelessType())) if ((typeType != NULL) && (!typeType->IsValuelessType()))
{ {
BfIRType irType = mBfIRBuilder->MapType(typeType);
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, mBfIRBuilder->mIgnoreWrites || staticVarName.StartsWith('#'));
globalValue = mBfIRBuilder->CreateGlobalVariable( globalValue = mBfIRBuilder->CreateGlobalVariable(
mBfIRBuilder->MapType(typeType), irType,
false, false,
BfIRLinkageType_External, BfIRLinkageType_External,
BfIRValue(), BfIRValue(),
@ -16601,6 +16655,10 @@ void BfModule::EmitGCMarkMembers()
if ((fieldDef->mIsStatic) && (!fieldDef->mIsConst)) if ((fieldDef->mIsStatic) && (!fieldDef->mIsConst))
{ {
StringT<128> staticVarName;
BfMangler::Mangle(staticVarName, mCompiler->GetMangleKind(), &fieldInst);
if (staticVarName.StartsWith('#'))
continue;
markVal = ReferenceStaticField(&fieldInst); markVal = ReferenceStaticField(&fieldInst);
} }
else if (!fieldDef->mIsStatic) else if (!fieldDef->mIsStatic)
@ -20368,7 +20426,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
else else
{ {
BfConstResolver constResolver(this); 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)) if ((defaultValue) && (defaultValue.mType != resolvedParamType))
{ {
SetAndRestoreValue<bool> prevIgnoreWrite(mBfIRBuilder->mIgnoreWrites, true); SetAndRestoreValue<bool> prevIgnoreWrite(mBfIRBuilder->mIgnoreWrites, true);

View file

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