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:
parent
24aaa22f7a
commit
25f44ae133
11 changed files with 294 additions and 75 deletions
29
BeefLibs/corlib/src/Compiler.bf
Normal file
29
BeefLibs/corlib/src/Compiler.bf
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue