1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-23 10:08:00 +02:00

Merge branch 'master' of https://github.com/beefytech/Beef into FuzzyAutoComplete

This commit is contained in:
Simon Lübeß 2021-12-17 18:05:39 +01:00
parent c2c7431620
commit b70745ef1e
48 changed files with 2975 additions and 918 deletions

View file

@ -1647,7 +1647,7 @@ void BfAutoComplete::CheckIdentifier(BfAstNode* identifierNode, bool isInExpress
{
"abstract", "base", "class", "const",
"delegate", "extern", "enum", "explicit", "extension", "function",
"interface", "in", "internal", "mixin", "namespace", "new",
"interface", "in", "implicit", "internal", "mixin", "namespace", "new",
"operator", "out", "override", "params", "private", "protected", "public", "readonly", "ref", "rettype", "return",
"scope", "sealed", "static", "struct", "this", "typealias",
"using", "virtual", "volatile", "T", "where"

View file

@ -420,6 +420,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mInternalTypeDef = NULL;
mPlatformTypeDef = NULL;
mCompilerTypeDef = NULL;
mCompilerGeneratorTypeDef = NULL;
mDiagnosticsDebugTypeDef = NULL;
mIDisposableTypeDef = NULL;
mIIntegerTypeDef = NULL;
@ -6765,6 +6766,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mInternalTypeDef = _GetRequiredType("System.Internal");
mPlatformTypeDef = _GetRequiredType("System.Platform");
mCompilerTypeDef = _GetRequiredType("System.Compiler");
mCompilerGeneratorTypeDef = _GetRequiredType("System.Compiler.Generator");
mDiagnosticsDebugTypeDef = _GetRequiredType("System.Diagnostics.Debug");
mIDisposableTypeDef = _GetRequiredType("System.IDisposable");
mIIntegerTypeDef = _GetRequiredType("System.IInteger");
@ -8107,6 +8109,149 @@ String BfCompiler::GetTypeDefList()
return result;
}
String BfCompiler::GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args)
{
if (typeInst == NULL)
{
auto type = mContext->mUnreifiedModule->ResolveTypeDef(typeDef, BfPopulateType_BaseType);
if (type != NULL)
typeInst = type->ToTypeInstance();
if (typeInst == NULL)
return "";
}
BfTypeVector typeVector;
typeVector.Add(typeInst);
auto generatorTypeInst = mContext->mUnreifiedModule->ResolveTypeDef(mCompilerGeneratorTypeDef)->ToTypeInstance();
auto methodDef = generatorTypeInst->mTypeDef->GetMethodByName(generatorMethodName);
auto moduleMethodInstance = mContext->mUnreifiedModule->GetMethodInstance(generatorTypeInst, methodDef, typeVector);
SetAndRestoreValue<BfMethodInstance*> prevMethodInstance(mContext->mUnreifiedModule->mCurMethodInstance, moduleMethodInstance.mMethodInstance);
SetAndRestoreValue<BfTypeInstance*> prevTypeInstance(mContext->mUnreifiedModule->mCurTypeInstance, typeInst);
BfExprEvaluator exprEvaluator(mContext->mUnreifiedModule);
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_Comptime;
SizedArray<BfIRValue, 1> irArgs;
if (args != NULL)
irArgs.Add(mContext->mUnreifiedModule->GetStringObjectValue(*args));
auto callResult = exprEvaluator.CreateCall(NULL, moduleMethodInstance.mMethodInstance, moduleMethodInstance.mFunc, false, irArgs, NULL, BfCreateCallFlags_None);
if (callResult.mValue.IsConst())
{
auto stringPtr = mContext->mUnreifiedModule->GetStringPoolString(callResult.mValue, mContext->mUnreifiedModule->mBfIRBuilder);
if (stringPtr != NULL)
return *stringPtr;
}
return "";
}
void BfCompiler::HandleGeneratorErrors(StringImpl& result)
{
if ((mPassInstance->mErrors.IsEmpty()) && (mPassInstance->mOutStream.IsEmpty()))
return;
result.Clear();
for (auto& msg : mPassInstance->mOutStream)
{
String error = msg;
error.Replace('\n', '\r');
result += "!error\t";
result += error;
result += "\n";
}
}
String BfCompiler::GetGeneratorTypeDefList()
{
String result;
BfProject* curProject = NULL;
Dictionary<BfProject*, int> projectIds;
BfResolvePassData resolvePassData;
SetAndRestoreValue<BfResolvePassData*> prevResolvePassData(mResolvePassData, &resolvePassData);
BfPassInstance passInstance(mSystem);
SetAndRestoreValue<BfPassInstance*> prevPassInstance(mPassInstance, &passInstance);
for (auto typeDef : mSystem->mTypeDefs)
{
if (typeDef->mProject->mDisabled)
continue;
if (typeDef->mIsPartial)
continue;
auto type = mContext->mUnreifiedModule->ResolveTypeDef(typeDef, BfPopulateType_BaseType);
if ((type != NULL) && (type->IsTypeInstance()))
{
auto typeInst = type->ToTypeInstance();
if ((typeInst->mBaseType != NULL) && (typeInst->mBaseType->IsInstanceOf(mCompilerGeneratorTypeDef)))
{
result += typeDef->mProject->mName;
result += ":";
result += BfTypeUtils::TypeToString(typeDef, BfTypeNameFlag_InternalName);
String nameString = GetGeneratorString(typeDef, typeInst, "GetName", NULL);
if (!nameString.IsEmpty())
result += "\t" + nameString;
result += "\n";
}
}
}
HandleGeneratorErrors(result);
return result;
}
String BfCompiler::GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args)
{
BfResolvePassData resolvePassData;
SetAndRestoreValue<BfResolvePassData*> prevResolvePassData(mResolvePassData, &resolvePassData);
BfPassInstance passInstance(mSystem);
SetAndRestoreValue<BfPassInstance*> prevPassInstance(mPassInstance, &passInstance);
Array<BfTypeDef*> typeDefs;
GetTypeDefs(typeName, typeDefs);
String result;
for (auto typeDef : typeDefs)
{
result += GetGeneratorString(typeDef, NULL, "InitUI", &args);
if (!result.IsEmpty())
break;
}
HandleGeneratorErrors(result);
return result;
}
String BfCompiler::GetGeneratorGenData(const StringImpl& typeName, const StringImpl& args)
{
BfResolvePassData resolvePassData;
SetAndRestoreValue<BfResolvePassData*> prevResolvePassData(mResolvePassData, &resolvePassData);
BfPassInstance passInstance(mSystem);
SetAndRestoreValue<BfPassInstance*> prevPassInstance(mPassInstance, &passInstance);
Array<BfTypeDef*> typeDefs;
GetTypeDefs(typeName, typeDefs);
String result;
for (auto typeDef : typeDefs)
{
result += GetGeneratorString(typeDef, NULL, "Generate", &args);
if (!result.IsEmpty())
break;
}
HandleGeneratorErrors(result);
return result;
}
struct TypeDefMatchHelper
{
public:
@ -8600,9 +8745,9 @@ String BfCompiler::GetTypeDefMatches(const StringImpl& searchStr)
return result;
}
String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
void BfCompiler::GetTypeDefs(const StringImpl& inTypeName, Array<BfTypeDef*>& typeDefs)
{
BfProject* project = NULL;
BfProject* project = NULL;
int idx = 0;
int sep = (int)inTypeName.IndexOf(':');
@ -8615,7 +8760,7 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
String typeName;
int genericCount = 0;
int pendingGenericCount = 0;
for ( ; idx < (int)inTypeName.length(); idx++)
for (; idx < (int)inTypeName.length(); idx++)
{
char c = inTypeName[idx];
if (c == '<')
@ -8626,7 +8771,7 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
genericCount++;
else if (c == '>')
{
pendingGenericCount = genericCount;
pendingGenericCount = genericCount;
genericCount = 0;
}
}
@ -8640,10 +8785,10 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
typeName += c;
}
}
bool isGlobals = false;
if (typeName == ":static")
{
{
typeName.clear();
isGlobals = true;
}
@ -8657,63 +8802,73 @@ String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
if (typeName[i] == '+')
typeName[i] = '.';
String result;
TypeDefMatchHelper matchHelper(result);
BfAtomComposite nameComposite;
BfAtomComposite nameComposite;
if ((typeName.IsEmpty()) || (mSystem->ParseAtomComposite(typeName, nameComposite)))
{
{
auto itr = mSystem->mTypeDefs.TryGet(nameComposite);
while (itr)
{
{
auto typeDef = *itr;
if ((!typeDef->mIsPartial) &&
(typeDef->mProject == project) &&
(typeDef->mFullName == nameComposite) &&
(typeDef->IsGlobalsContainer() == isGlobals) &&
(typeDef->GetSelfGenericParamCount() == pendingGenericCount))
{
auto refNode = typeDef->GetRefNode();
result += "S";
matchHelper.AddLocation(refNode);
result += "\n";
for (auto fieldDef : typeDef->mFields)
{
result += "F";
result += fieldDef->mName;
matchHelper.AddFieldDef(fieldDef);
}
for (auto propDef : typeDef->mProperties)
{
if (propDef->GetRefNode() == NULL)
continue;
result += "P";
matchHelper.AddPropertyDef(typeDef, propDef);
}
for (auto methodDef : typeDef->mMethods)
{
if ((methodDef->mMethodType != BfMethodType_Normal) &&
(methodDef->mMethodType != BfMethodType_Mixin) &&
(methodDef->mMethodType != BfMethodType_Ctor) &&
(methodDef->mMethodType != BfMethodType_Dtor))
continue;
if (methodDef->mMethodDeclaration == NULL)
continue;
result += "M";
matchHelper.AddMethodDef(methodDef);
}
{
typeDefs.Add(typeDef);
}
itr.MoveToNextHashMatch();
}
}
}
String BfCompiler::GetTypeDefInfo(const StringImpl& inTypeName)
{
Array<BfTypeDef*> typeDefs;
GetTypeDefs(inTypeName, typeDefs);
String result;
TypeDefMatchHelper matchHelper(result);
for (auto typeDef : typeDefs)
{
auto refNode = typeDef->GetRefNode();
result += "S";
matchHelper.AddLocation(refNode);
result += "\n";
for (auto fieldDef : typeDef->mFields)
{
result += "F";
result += fieldDef->mName;
matchHelper.AddFieldDef(fieldDef);
}
for (auto propDef : typeDef->mProperties)
{
if (propDef->GetRefNode() == NULL)
continue;
result += "P";
matchHelper.AddPropertyDef(typeDef, propDef);
}
for (auto methodDef : typeDef->mMethods)
{
if ((methodDef->mMethodType != BfMethodType_Normal) &&
(methodDef->mMethodType != BfMethodType_Mixin) &&
(methodDef->mMethodType != BfMethodType_Ctor) &&
(methodDef->mMethodType != BfMethodType_Dtor))
continue;
if (methodDef->mMethodDeclaration == NULL)
continue;
result += "M";
matchHelper.AddMethodDef(methodDef);
}
}
return result;
}
@ -8990,6 +9145,30 @@ BF_EXPORT void BF_CALLTYPE BfCompiler_ProgramDone()
#endif
}
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetGeneratorTypeDefList(BfCompiler* bfCompiler)
{
String& outString = *gTLStrReturn.Get();
outString.clear();
outString = bfCompiler->GetGeneratorTypeDefList();
return outString.c_str();
}
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetGeneratorInitData(BfCompiler* bfCompiler, char* typeDefName, char* args)
{
String& outString = *gTLStrReturn.Get();
outString.clear();
outString = bfCompiler->GetGeneratorInitData(typeDefName, args);
return outString.c_str();
}
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetGeneratorGenData(BfCompiler* bfCompiler, char* typeDefName, char* args)
{
String& outString = *gTLStrReturn.Get();
outString.clear();
outString = bfCompiler->GetGeneratorGenData(typeDefName, args);
return outString.c_str();
}
BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetTypeDefList(BfCompiler* bfCompiler)
{
String& outString = *gTLStrReturn.Get();

View file

@ -374,6 +374,7 @@ public:
BfTypeDef* mInternalTypeDef;
BfTypeDef* mPlatformTypeDef;
BfTypeDef* mCompilerTypeDef;
BfTypeDef* mCompilerGeneratorTypeDef;
BfTypeDef* mDiagnosticsDebugTypeDef;
BfTypeDef* mIDisposableTypeDef;
BfTypeDef* mIIntegerTypeDef;
@ -511,9 +512,15 @@ public:
void ProcessAutocompleteTempType();
void GetSymbolReferences();
void Cancel();
void RequestFastFinish();
void RequestFastFinish();
String GetTypeDefList();
String GetTypeDefMatches(const StringImpl& searchSrc);
String GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeInst, const StringImpl& generatorMethodName, const StringImpl* args);
void HandleGeneratorErrors(StringImpl& result);
String GetGeneratorTypeDefList();
String GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args);
String GetGeneratorGenData(const StringImpl& typeName, const StringImpl& args);
String GetTypeDefMatches(const StringImpl& searchSrc);
void GetTypeDefs(const StringImpl& typeName, Array<BfTypeDef*>& typeDefs);
String GetTypeDefInfo(const StringImpl& typeName);
int GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer);

View file

@ -892,6 +892,9 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
return;
}
if ((typeInst->IsBoxed()) && (typeInst->mTypeDef->mEmitParent != NULL))
typeInst->mTypeDef = typeInst->mTypeDef->mEmitParent;
if (mSystem->mWorkspaceConfigChanged)
{
typeInst->mTypeOptionsIdx = -2;
@ -1060,8 +1063,12 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild
if (typeInst->mTypeDef->mEmitParent != NULL)
{
auto emitTypeDef = typeInst->mTypeDef;
typeInst->mTypeDef = emitTypeDef->mEmitParent;
delete emitTypeDef;
typeInst->mTypeDef = emitTypeDef->mEmitParent;
BfLogSysM("Type %p queueing delete of typeDef %p, resetting typeDef to %p\n", typeInst, emitTypeDef, typeInst->mTypeDef);
emitTypeDef->mDefState = BfTypeDef::DefState_Deleted;
AutoCrit autoCrit(mSystem->mDataLock);
BF_ASSERT(!mSystem->mTypeDefDeleteQueue.Contains(emitTypeDef));
mSystem->mTypeDefDeleteQueue.push_back(emitTypeDef);
}
//typeInst->mTypeDef->ClearEmitted();
@ -1912,10 +1919,17 @@ void BfContext::UpdateRevisedTypes()
if (typeDef->mEmitParent != NULL)
{
auto emitTypeDef = typeDef;
typeDef = typeDef->mEmitParent;
if (typeDef->mNextRevision != NULL)
emitTypeDef->mDefState = BfTypeDef::DefState_EmittedDirty;
if (typeDef->mDefState == BfTypeDef::DefState_Deleted)
{
typeInst->mTypeDef = typeDef->mEmitParent;
}
else
{
auto emitTypeDef = typeDef;
typeDef = typeDef->mEmitParent;
if (typeDef->mNextRevision != NULL)
emitTypeDef->mDefState = BfTypeDef::DefState_EmittedDirty;
}
}
if (typeDef->mProject->mDisabled)

View file

@ -3578,7 +3578,7 @@ void BfExprEvaluator::GetLiteral(BfAstNode* refNode, const BfVariant& variant)
if ((mExpectingType != NULL) && (mExpectingType->IsIntegral()) && (mExpectingType->IsChar() == IsCharType(variant.mTypeCode)))
{
auto primType = (BfPrimitiveType*)mExpectingType;
if (mModule->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, variant.mInt64))
if (mModule->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, variant.mUInt64))
{
mResult = BfTypedValue(mModule->mBfIRBuilder->CreateConst(primType->mTypeDef->mTypeCode, variant.mUInt64), mExpectingType);
break;
@ -5090,7 +5090,9 @@ void BfExprEvaluator::ResolveArgValues(BfResolvedArgs& resolvedArgs, BfResolveAr
BfExprEvaluator exprEvaluator(mModule);
exprEvaluator.mResolveGenericParam = (flags & BfResolveArgsFlag_AllowUnresolvedTypes) == 0;
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr);
exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(exprEvaluator.mBfEvalExprFlags | BfEvalExprFlags_AllowRefExpr | BfEvalExprFlags_AllowOutExpr |
(mBfEvalExprFlags & (BfEvalExprFlags_Comptime)));
bool handled = false;
bool evaluated = false;
@ -6373,16 +6375,23 @@ void BfExprEvaluator::FinishDeferredEvals(BfResolvedArgs& argValues)
auto variableDeclaration = BfNodeDynCast<BfVariableDeclaration>((*argValues.mArguments)[argIdx]);
if ((variableDeclaration != NULL) && (variableDeclaration->mNameNode != NULL))
{
BfLocalVariable* localVar = new BfLocalVariable();
localVar->mName = variableDeclaration->mNameNode->ToString();
localVar->mResolvedType = mModule->GetPrimitiveType(BfTypeCode_Var);
localVar->mAddr = mModule->mBfIRBuilder->GetFakeVal();
localVar->mReadFromId = 0;
localVar->mWrittenToId = 0;
localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
mModule->CheckVariableDef(localVar);
localVar->Init();
mModule->AddLocalVariableDef(localVar, true);
if (mModule->mCurMethodState == NULL)
{
mModule->Fail("Illegal local variable", variableDeclaration);
}
else
{
BfLocalVariable* localVar = new BfLocalVariable();
localVar->mName = variableDeclaration->mNameNode->ToString();
localVar->mResolvedType = mModule->GetPrimitiveType(BfTypeCode_Var);
localVar->mAddr = mModule->mBfIRBuilder->GetFakeVal();
localVar->mReadFromId = 0;
localVar->mWrittenToId = 0;
localVar->mAssignedKind = BfLocalVarAssignKind_Unconditional;
mModule->CheckVariableDef(localVar);
localVar->Init();
mModule->AddLocalVariableDef(localVar, true);
}
}
}
}
@ -10139,6 +10148,12 @@ void BfExprEvaluator::Visit(BfInitializerExpression* initExpr)
for (auto elementExpr : initExpr->mValues)
{
if ((mBfEvalExprFlags & BfEvalExprFlags_Comptime) != 0)
{
mModule->Fail("Comptime cannot evaluate initializer expressions", elementExpr);
break;
}
bool wasValidInitKind = false;
if (auto assignExpr = BfNodeDynCast<BfAssignmentExpression>(elementExpr))
@ -11133,8 +11148,7 @@ void BfExprEvaluator::Visit(BfCastExpression* castExpr)
bool BfExprEvaluator::IsExactMethodMatch(BfMethodInstance* methodA, BfMethodInstance* methodB, bool ignoreImplicitParams)
{
if (methodA->mReturnType != methodB->mReturnType)
return false;
return false;
int implicitParamCountA = methodA->GetImplicitParamCount();
if (methodA->HasExplicitThis())
implicitParamCountA++;
@ -11696,7 +11710,11 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
}
else
{
if (!IsExactMethodMatch(methodInstance, bindMethodInstance, true))
bool isExactMethodMatch = IsExactMethodMatch(methodInstance, bindMethodInstance, true);
if ((mExpectingType != NULL) && (mExpectingType->IsFunction()) && (methodInstance->mMethodDef->mIsMutating != bindMethodInstance->mMethodDef->mIsMutating))
isExactMethodMatch = false;
if (!isExactMethodMatch)
{
if (bindResult.mCheckedMultipleMethods)
{
@ -11704,8 +11722,8 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
}
else
{
mModule->Fail(StrFormat("Method '%s' does not match %s '%s'", mModule->MethodToString(bindMethodInstance).c_str(), bindTypeName,
{
mModule->Fail(StrFormat("Method '%s' does not match %s '%s'", mModule->MethodToString(bindMethodInstance, (BfMethodNameFlags)(BfMethodNameFlag_ResolveGenericParamNames | BfMethodNameFlag_IncludeReturnType | BfMethodNameFlag_IncludeMut)).c_str(), bindTypeName,
mModule->TypeToString(delegateTypeInstance).c_str()), delegateBindExpr->mTarget);
}
mResult = BfTypedValue();
@ -11725,7 +11743,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
}
bool hasIncompatibleCallingConventions = !mModule->mSystem->IsCompatibleCallingConvention(methodInstance->mCallingConvention, bindMethodInstance->mCallingConvention);
auto _GetInvokeMethodName = [&]()
{
String methodName = "Invoke$";
@ -11789,7 +11807,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (mExpectingType->IsFunction())
{
BfIRValue result;
if ((hasIncompatibleCallingConventions) && (mModule->HasCompiledOutput()))
if ((hasIncompatibleCallingConventions) && (mModule->HasExecutedOutput()))
{
//
{
@ -11799,11 +11817,14 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (result)
{
String methodName = _GetInvokeMethodName();
String methodName = _GetInvokeMethodName();
SizedArray<BfIRType, 8> irParamTypes;
BfIRType irReturnType;
bindMethodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
methodInstance->GetIRFunctionInfo(mModule, irReturnType, irParamTypes);
int thisFuncParamIdx = methodInstance->GetThisIdx();
int thisBindParamIdx = methodInstance->GetThisIdx();
auto prevActiveFunction = mModule->mBfIRBuilder->GetActiveFunction();
auto prevInsertBlock = mModule->mBfIRBuilder->GetInsertBlock();
@ -11949,7 +11970,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
// Do we need a special delegate type for this?
if (((captureThisByValue) || (needsSplat) || (implicitParamCount > 0) /*|| (hasIncompatibleCallingConventions)*/) &&
(mModule->HasCompiledOutput()))
(mModule->HasExecutedOutput()))
{
hasCaptures = true;
auto curProject = mModule->mCurTypeInstance->mTypeDef->mProject;
@ -12030,7 +12051,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
// Do we need specialized calling code for this?
BfIRValue funcValue;
if (((needsSplat) || (implicitParamCount > 0) || (hasIncompatibleCallingConventions)) &&
(mModule->HasCompiledOutput()))
(mModule->HasExecutedOutput()))
{
int fieldIdx = 0;
for (int implicitParamIdx = bindMethodInstance->HasThis() ? -1 : 0; implicitParamIdx < implicitParamCount; implicitParamIdx++)
@ -12208,7 +12229,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
// >> delegate.mTarget = bindResult.mTarget
BfIRValue valPtr;
if (mModule->HasCompiledOutput())
if (mModule->HasExecutedOutput())
{
if ((implicitParamCount > 0) || (needsSplat)) // Point back to self, it contains capture data
valPtr = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->GetPrimitiveType(BfTypeCode_NullPtr));
@ -12226,7 +12247,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
if (!funcValue)
{
if ((mModule->HasCompiledOutput()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
if ((mModule->HasExecutedOutput()) && (!mModule->mBfIRBuilder->mIgnoreWrites))
mModule->AssertErrorState();
return;
}
@ -13188,7 +13209,7 @@ BfLambdaInstance* BfExprEvaluator::GetLambdaInstance(BfLambdaBindExpression* lam
mModule->mIncompleteMethodCount++;
SetAndRestoreValue<BfClosureState*> prevClosureState(mModule->mCurMethodState->mClosureState, &closureState);
if (mModule->HasCompiledOutput())
if (mModule->HasExecutedOutput())
mModule->SetupIRMethod(methodInstance, methodInstance->mIRFunction, methodInstance->mAlwaysInline);
// This keeps us from giving errors twice. ProcessMethod can give errors when we capture by value but needed to
@ -14415,7 +14436,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
{
if (!bindResult.mFunc)
{
BF_ASSERT((!mModule->HasCompiledOutput()) || (mModule->mBfIRBuilder->mIgnoreWrites));
BF_ASSERT((!mModule->HasExecutedOutput()) || (mModule->mBfIRBuilder->mIgnoreWrites));
appendSizeValue = mModule->GetConstValue(0);
}
else
@ -19717,7 +19738,7 @@ void BfExprEvaluator::Visit(BfIndexerExpression* indexerExpr)
}
}
}
else if (((mModule->HasCompiledOutput()) || (mModule->mIsComptimeModule)) &&
else if (((mModule->HasExecutedOutput()) || (mModule->mIsComptimeModule)) &&
(wantsChecks))
{
if (checkedKind == BfCheckedKind_NotSet)

View file

@ -857,6 +857,27 @@ BfIRValue BfIRConstHolder::CreateConstArrayZero(int count)
return irValue;
}
BfIRValue BfIRConstHolder::CreateConstBitCast(BfIRValue val, BfIRType type)
{
auto constVal = GetConstant(val);
auto bitCast = mTempAlloc.Alloc<BfConstantBitCast>();
if ((constVal == NULL) || (constVal->IsNull()))
bitCast->mConstType = BfConstType_BitCastNull;
else
bitCast->mConstType = BfConstType_BitCast;
BF_ASSERT(val.mId != -1);
bitCast->mTarget = val.mId;
bitCast->mToType = type;
BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(bitCast));
#ifdef CHECK_CONSTHOLDER
castedVal.mHolder = this;
#endif
BF_ASSERT((void*)GetConstant(castedVal) == (void*)bitCast);
return castedVal;
}
BfIRValue BfIRConstHolder::CreateTypeOf(BfType* type)
{
BfTypeOf_Const* typeOf = mTempAlloc.Alloc<BfTypeOf_Const>();
@ -2970,10 +2991,10 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
diFieldTypes.push_back(memberType);
}
bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
for (auto& fieldInstanceRef : typeInstance->mFieldInstances)
bool isPayloadEnum = (typeInstance->IsEnum()) && (!typeInstance->IsTypedPrimitive());
for (int fieldIdx = 0; fieldIdx < typeInstance->mFieldInstances.mSize; fieldIdx++)
{
auto fieldInstance = &fieldInstanceRef;
auto fieldInstance = &typeInstance->mFieldInstances[fieldIdx];
if (!fieldInstance->mFieldIncluded)
continue;
auto fieldDef = fieldInstance->GetFieldDef();
@ -3091,18 +3112,15 @@ void BfIRBuilder::CreateDbgTypeDefinition(BfType* type)
{
staticValue = ConstToMemory(staticValue);
wasMadeAddr = true;
}
else if (resolvedFieldType->IsPointer())
}
else if (constant->mTypeCode == BfTypeCode_StringId)
{
int stringId = constant->mInt32;
const StringImpl& str = mModule->mContext->mStringObjectIdMap[stringId].mString;
staticValue = mModule->GetStringCharPtr(str);
}
else if (constant->mTypeCode == BfTypeCode_StringId)
{
int stringId = constant->mInt32;
const StringImpl& str = mModule->mContext->mStringObjectIdMap[stringId].mString;
staticValue = mModule->GetStringObjectValue(str);
if (resolvedFieldType->IsPointer())
staticValue = mModule->GetStringCharPtr(str);
else
staticValue = mModule->GetStringObjectValue(str);
}
else
{
@ -4417,25 +4435,7 @@ BfIRValue BfIRBuilder::CreateNot(BfIRValue val)
BfIRValue BfIRBuilder::CreateBitCast(BfIRValue val, BfIRType type)
{
if (val.IsConst())
{
auto constVal = GetConstant(val);
auto bitCast = mTempAlloc.Alloc<BfConstantBitCast>();
if (constVal->IsNull())
bitCast->mConstType = BfConstType_BitCastNull;
else
bitCast->mConstType = BfConstType_BitCast;
bitCast->mTarget = val.mId;
bitCast->mToType = type;
BfIRValue castedVal(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(bitCast));
#ifdef CHECK_CONSTHOLDER
castedVal.mHolder = this;
#endif
BF_ASSERT((void*)GetConstant(castedVal) == (void*)bitCast);
return castedVal;
}
return CreateConstBitCast(val, type);
auto retVal = WriteCmd(BfIRCmd_BitCast, val, type);
NEW_CMD_INSERTED_IRVALUE;
return retVal;

View file

@ -934,6 +934,7 @@ public:
BfIRValue CreateConstAggCE(BfIRType type, addr_ce ptr);
BfIRValue CreateConstArrayZero(BfIRType type, int count);
BfIRValue CreateConstArrayZero(int count);
BfIRValue CreateConstBitCast(BfIRValue val, BfIRType type);
BfIRValue CreateTypeOf(BfType* type);
BfIRValue CreateTypeOf(BfType* type, BfIRValue typeData);
BfIRValue GetUndefConstValue(BfIRType type);

View file

@ -7889,7 +7889,7 @@ bool BfModule::CheckGenericConstraints(const BfGenericParamSource& genericParamS
{
if (BfIRConstHolder::IsInt(primType->mTypeDef->mTypeCode))
{
if (!mCompiler->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, constExprValueType->mValue.mInt64))
if (!mCompiler->mSystem->DoesLiteralFit(primType->mTypeDef->mTypeCode, constExprValueType->mValue.mUInt64))
{
if ((!ignoreErrors) && (PreFail()))
*errorOut = Fail(StrFormat("Const generic argument '%s', declared with const '%lld', does not fit into const constraint '%s' for '%s'", genericParamInst->GetName().c_str(),
@ -9617,6 +9617,11 @@ bool BfModule::HasCompiledOutput()
return (!mSystem->mIsResolveOnly) && (mGeneratesCode) && (!mIsComptimeModule);
}
bool BfModule::HasExecutedOutput()
{
return ((!mSystem->mIsResolveOnly) && (mGeneratesCode)) || (mIsComptimeModule);
}
// We will skip the object access check for any occurrences of this value
void BfModule::SkipObjectAccessCheck(BfTypedValue typedVal)
{
@ -10519,7 +10524,7 @@ bool BfModule::HasMixin(BfTypeInstance* typeInstance, const StringImpl& methodNa
}
StringT<128> BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodNameFlags methodNameFlags, BfTypeVector* typeGenericArgs, BfTypeVector* methodGenericArgs)
{
{
auto methodDef = methodInst->mMethodDef;
bool allowResolveGenericParamNames = ((methodNameFlags & BfMethodNameFlag_ResolveGenericParamNames) != 0);
@ -10764,8 +10769,16 @@ StringT<128> BfModule::MethodToString(BfMethodInstance* methodInst, BfMethodName
if (accessorString.length() != 0)
{
methodName += " " + accessorString;
methodName += " ";
methodName += accessorString;
}
if ((methodNameFlags & BfMethodNameFlag_IncludeMut) != 0)
{
if ((methodDef->mIsMutating) && (methodInst->GetOwner()->IsValueType()))
methodName += " mut";
}
return methodName;
}
@ -10860,8 +10873,17 @@ void BfModule::CurrentAddToConstHolder(BfIRValue& irVal)
auto origConst = irVal;
if ((constant->mConstType == BfConstType_BitCast) || (constant->mConstType == BfConstType_BitCastNull))
{
auto bitcast = (BfConstantBitCast*)constant;
constant = mBfIRBuilder->GetConstantById(bitcast->mTarget);
auto bitcast = (BfConstantBitCast*)constant;
BfIRValue newVal;
if (bitcast->mTarget)
{
newVal = BfIRValue(BfIRValueFlags_Const, bitcast->mTarget);
CurrentAddToConstHolder(newVal);
}
else
newVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstNull();
irVal = mCurTypeInstance->GetOrCreateConstHolder()->CreateConstBitCast(newVal, bitcast->mToType);
return;
}
irVal = mCurTypeInstance->CreateConst(constant, mBfIRBuilder);
@ -10986,7 +11008,7 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
wantType = mContext->mTypes[constant->mIRType.mId];
if (wantType == NULL)
return constHolder->CreateConstNull();
return mBfIRBuilder->CreateConstNull();
return GetDefaultValue(wantType);
}
@ -11034,8 +11056,21 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
return mBfIRBuilder->CreateIntToPtr(ConstantToCurrent(fromTarget, constHolder, NULL), toIRType);
}
if ((constant->mConstType == BfConstType_BitCast) || (constant->mConstType == BfConstType_BitCastNull))
{
auto bitcast = (BfConstantBitCast*)constant;
auto fromTarget = constHolder->GetConstantById(bitcast->mTarget);
BfIRType toIRType = bitcast->mToType;
if (toIRType.mKind == BfIRTypeData::TypeKind_TypeId)
{
auto toType = mContext->mTypes[toIRType.mId];
toIRType = mBfIRBuilder->MapType(toType);
}
return mBfIRBuilder->CreateBitCast(ConstantToCurrent(fromTarget, constHolder, NULL), toIRType);
}
if (constant->mConstType == BfConstType_Agg)
{
{
auto constArray = (BfConstantAgg*)constant;
if ((wantType == NULL) && (constArray->mType.mKind == BfIRTypeData::TypeKind_TypeId))
@ -14456,7 +14491,7 @@ BfLocalVariable* BfModule::AddLocalVariableDef(BfLocalVariable* localVarDef, boo
if ((localVarDef->mNameNode != NULL) && (mCurMethodInstance != NULL))
{
bool isClosureProcessing = (mCurMethodState->mClosureState != NULL) && (!mCurMethodState->mClosureState->mCapturing);
if ((!isClosureProcessing) && (mCompiler->mResolvePassData != NULL) && (localVarDef->mNameNode != NULL) && (!mIsComptimeModule))
if ((!isClosureProcessing) && (mCompiler->mResolvePassData != NULL) && (localVarDef->mNameNode != NULL) && (rootMethodState->mMethodInstance != NULL) && (!mIsComptimeModule))
mCompiler->mResolvePassData->HandleLocalReference(localVarDef->mNameNode, rootMethodState->mMethodInstance->GetOwner()->mTypeDef, rootMethodState->mMethodInstance->mMethodDef, localVarDef->mLocalVarId);
}
@ -15273,14 +15308,18 @@ void BfModule::AssertErrorState()
{
if (mCurTypeInstance->mTypeFailed)
return;
if (mCurTypeInstance->mTypeDef->mSource->mParsingFailed)
if ((mCurTypeInstance->mTypeDef->GetDefinition()->mSource != NULL) && (mCurTypeInstance->mTypeDef->GetDefinition()->mSource->mParsingFailed))
return;
}
if (mCurMethodInstance != NULL)
{
if ((mCurMethodInstance->mMethodDef->mDeclaringType != NULL) && (mCurMethodInstance->mMethodDef->mDeclaringType->mSource->mParsingFailed))
if ((mCurMethodInstance->mMethodDef->mDeclaringType != NULL) &&
(mCurMethodInstance->mMethodDef->mDeclaringType->mSource != NULL) &&
(mCurMethodInstance->mMethodDef->mDeclaringType->mSource->mParsingFailed))
return;
if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) && (mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->mSource->mParsingFailed))
if ((mCurMethodState != NULL) && (mCurMethodState->mMixinState != NULL) &&
(mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->mSource != NULL) &&
(mCurMethodState->mMixinState->mMixinMethodInstance->mMethodDef->mDeclaringType->mSource->mParsingFailed))
return;
}
@ -16203,6 +16242,8 @@ void BfModule::EmitDtorBody()
BfIRValue BfModule::CreateDllImportGlobalVar(BfMethodInstance* methodInstance, bool define)
{
BF_ASSERT(methodInstance->mIsReified);
auto typeInstance = methodInstance->GetOwner();
bool foundDllImportAttr = false;
@ -16467,7 +16508,7 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
auto elementType = refType->mElementType;
PopulateType(elementType, BfPopulateType_Data);
addDeref = elementType->mSize;
if ((addDeref <= 0) && (!elementType->IsValuelessType()))
if ((addDeref <= 0) && (!elementType->IsValuelessType()) && (!elementType->IsOpaque()))
AssertErrorState();
}
if ((resolvedTypeRef->IsComposite()) && (!resolvedTypeRef->IsTypedPrimitive()))
@ -17041,7 +17082,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
break;
}
if ((HasCompiledOutput()) && (matchedMethod != NULL))
if ((HasExecutedOutput()) && (matchedMethod != NULL))
{
SizedArray<BfIRValue, 1> args;
auto ctorBodyMethodInstance = GetMethodInstance(mCurTypeInstance->mBaseType, matchedMethod, BfTypeVector());
@ -18486,7 +18527,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
return;
}
if (HasCompiledOutput())
if (HasExecutedOutput())
{
BF_ASSERT(mIsModuleMutable);
}
@ -19713,7 +19754,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
skipBody = true;
skipEndChecks = true;
if ((HasCompiledOutput()) || (mIsComptimeModule))
if (HasExecutedOutput())
{
// Clear out DebugLoc - to mark the ".addr" code as part of prologue
mBfIRBuilder->ClearDebugLocation();
@ -19743,12 +19784,8 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
mBfIRBuilder->CreateRetVoid();
}
else
{
BF_ASSERT(!innerMethodInstance.mMethodInstance->mMethodDef->mDeclaringType->IsEmitted());
{
auto innerMethodDef = innerMethodInstance.mMethodInstance->mMethodDef;
if (innerType->mTypeDef->IsEmitted())
innerMethodDef = innerType->mTypeDef->mEmitParent->mMethods[innerMethodDef->mIdx];
BF_ASSERT(innerMethodDef == methodDef);
SizedArray<BfIRValue, 8> innerParams;
@ -19977,7 +20014,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
else if ((mCurTypeInstance->IsEnum()) && (!mCurTypeInstance->IsBoxed()) && (methodDef->mName == BF_METHODNAME_TO_STRING))
{
auto enumType = ResolveTypeDef(mCompiler->mEnumTypeDef);
if ((HasCompiledOutput()) || (mIsComptimeModule))
if (HasExecutedOutput())
{
EmitEnumToStringBody();
}
@ -19990,7 +20027,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
else if ((mCurTypeInstance->IsTuple()) && (!mCurTypeInstance->IsBoxed()) && (methodDef->mName == BF_METHODNAME_TO_STRING))
{
auto enumType = ResolveTypeDef(mCompiler->mEnumTypeDef);
if ((HasCompiledOutput()) || (mIsComptimeModule))
if (HasExecutedOutput())
{
EmitTupleToStringBody();
}
@ -20032,7 +20069,7 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
{
mBfIRBuilder->CreateRetVoid();
}
else if ((HasCompiledOutput()) || (mIsComptimeModule))
else if (HasExecutedOutput())
{
String autoPropName = typeDef->GetAutoPropertyName(propertyDeclaration);
BfFieldInstance* fieldInstance = GetFieldByName(mCurTypeInstance, autoPropName);
@ -22782,18 +22819,6 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
//BF_ASSERT(mCompiler->IsAutocomplete());
BfLogSysM("DoMethodDeclaration isTemporaryFunc bailout\n");
return; // Bail out early for autocomplete pass
}
if ((methodInstance->GetImportCallKind() != BfImportCallKind_None) && (!mBfIRBuilder->mIgnoreWrites) && (!methodInstance->mIRFunction))
{
BfLogSysM("DllImportGlobalVar DoMethodDeclaration processing %p\n", methodInstance);
// If this is in an extension then we did create the global variable already in the original obj
bool doDefine = mExtensionCount == 0;
BfIRValue dllImportGlobalVar = CreateDllImportGlobalVar(methodInstance, doDefine);
func = mBfIRBuilder->GetFakeVal();
methodInstance->mIRFunction = func;
BF_ASSERT(dllImportGlobalVar);
mFuncReferences[mCurMethodInstance] = dllImportGlobalVar;
}
//TODO: We used to have this (this != mContext->mExternalFuncModule) check, but it caused us to keep around

View file

@ -1633,6 +1633,7 @@ public:
bool IsTargetingBeefBackend();
bool WantsLifetimes();
bool HasCompiledOutput();
bool HasExecutedOutput();
void SkipObjectAccessCheck(BfTypedValue typedVal);
void EmitObjectAccessCheck(BfTypedValue typedVal);
void EmitEnsureInstructionAt();

View file

@ -2076,6 +2076,9 @@ void BfModule::FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInst
void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode)
{
for (int ifaceTypeId : ceEmitContext->mInterfaces)
typeInstance->mCeTypeInfo->mPendingInterfaces.Add(ifaceTypeId);
if (ceEmitContext->mEmitData.IsEmpty())
return;
@ -2198,7 +2201,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
}
}
}
else if (!ceEmitContext->mEmitData.IsEmpty())
else if (ceEmitContext->HasEmissions())
{
if (typeInstance->mCeTypeInfo == NULL)
typeInstance->mCeTypeInfo = new BfCeTypeInfo();
@ -2210,7 +2213,7 @@ void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance*
typeInstance->mCeTypeInfo->mNext->mTypeIFaceMap[typeId] = entry;
}
if (!ceEmitContext->mEmitData.IsEmpty())
if (ceEmitContext->HasEmissions())
{
String ctxStr = "comptime ApplyToType of ";
ctxStr += TypeToString(attrType);
@ -2747,7 +2750,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
resolvedTypeRef->mSize = typeInstance->mAlign = mSystem->mPtrSize;
}
BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()) || (typeInstance->mCeTypeInfo != NULL));
BF_ASSERT((typeInstance->mMethodInstanceGroups.size() == 0) || (typeInstance->mMethodInstanceGroups.size() == typeDef->mMethods.size()) || (typeInstance->mCeTypeInfo != NULL) || (typeInstance->IsBoxed()));
typeInstance->mMethodInstanceGroups.Resize(typeDef->mMethods.size());
for (int i = 0; i < (int)typeInstance->mMethodInstanceGroups.size(); i++)
{
@ -2927,6 +2930,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
{
bool hadType = false;
BfAstNode* deferredErrorNode = NULL;
char* deferredError = NULL;
for (auto baseTypeRef : typeDef->mBaseTypes)
{
SetAndRestoreValue<BfTypeReference*> prevTypeRef(mContext->mCurTypeState->mCurBaseTypeRef, baseTypeRef);
@ -2946,12 +2952,14 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
}
else
{
Fail("Underlying enum type already specified", baseTypeRef);
deferredError = "Underlying enum type already specified";
deferredErrorNode = baseTypeRef;
}
}
else
{
Fail("Invalid underlying enum type", baseTypeRef);
deferredError = "Invalid underlying enum type";
deferredErrorNode = baseTypeRef;
}
}
else
@ -2961,6 +2969,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
}
}
if (deferredError != NULL)
Fail(deferredError, deferredErrorNode, true);
if (underlyingType == NULL)
{
underlyingType = GetPrimitiveType(BfTypeCode_Int64);
@ -3305,6 +3316,27 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
wantPopulateInterfaces = true;
}
if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty()))
{
for (auto ifaceTypeId : typeInstance->mCeTypeInfo->mPendingInterfaces)
{
auto ifaceType = mContext->mTypes[ifaceTypeId];
if ((ifaceType == NULL) || (!ifaceType->IsInterface()))
continue;
auto ifaceInst = ifaceType->ToTypeInstance();
if (ifaceSet.Add(ifaceInst))
{
// Not base type
BfInterfaceDecl ifaceDecl;
ifaceDecl.mIFaceTypeInst = ifaceInst;
ifaceDecl.mTypeRef = NULL;
ifaceDecl.mDeclaringType = typeDef->GetDefinition();
interfaces.Add(ifaceDecl);
}
}
}
if (_CheckTypeDone())
return;
@ -3694,6 +3726,25 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
if (innerType->IsIncomplete())
PopulateType(innerType, BfPopulateType_Data);
auto innerTypeInst = innerType->ToTypeInstance();
if (innerTypeInst != NULL)
{
if (typeInstance->mTypeDef != innerTypeInst->mTypeDef)
{
// Rebuild with proper typedef (generally from inner type comptime emission)
typeInstance->mTypeDef = innerTypeInst->mTypeDef;
DoPopulateType(resolvedTypeRef, populateType);
return;
}
while (typeInstance->mInterfaces.mSize < innerTypeInst->mInterfaces.mSize)
{
auto ifaceEntry = innerTypeInst->mInterfaces[typeInstance->mInterfaces.mSize];
typeInstance->mInterfaces.Add(ifaceEntry);
AddDependency(ifaceEntry.mInterfaceType, typeInstance, BfDependencyMap::DependencyFlag_ImplementsInterface);
}
}
auto baseType = typeInstance->mBaseType;
dataPos = baseType->mInstSize;
int alignSize = BF_MAX(innerType->mAlign, baseType->mInstAlign);
@ -3997,9 +4048,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
}
if ((typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit) && (tryCE))
{
{
BF_ASSERT(!typeInstance->mTypeDef->IsEmitted());
if (typeInstance->mCeTypeInfo != NULL)
typeInstance->mCeTypeInfo->mPendingInterfaces.Clear();
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
bool hadNewMembers = false;
DoCEEmit(typeInstance, hadNewMembers);
@ -4054,6 +4108,9 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
}
}
if ((typeInstance->mCeTypeInfo != NULL) && (!typeInstance->mCeTypeInfo->mPendingInterfaces.IsEmpty()))
hadNewMembers = true;
if ((typeInstance->mTypeDef->IsEmitted()) && (typeInstance->mCeTypeInfo == NULL))
{
BF_ASSERT(mCompiler->mCanceling);
@ -5658,16 +5715,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
}
else
{
auto matchedMethodDef = matchedMethod->mMethodDef;
if (matchedMethodDef->mDeclaringType->IsEmitted())
{
Fail("Boxed interface binding error to emitted method", mCurTypeInstance->mTypeDef->GetRefNode());
continue;
}
if (underlyingTypeInstance->mTypeDef->IsEmitted())
matchedMethodDef = underlyingTypeInstance->mTypeDef->mEmitParent->mMethods[matchedMethodDef->mIdx];
auto matchedMethodDef = matchedMethod->mMethodDef;
if (!matchedMethod->mIsForeignMethodDef)
{
BfMethodInstanceGroup* boxedMethodInstanceGroup = &typeInstance->mMethodInstanceGroups[matchedMethod->mMethodDef->mIdx];
@ -5676,7 +5724,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
VerifyOnDemandMethods();
}
}
}
auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None;
methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly);
@ -11505,29 +11553,37 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
{
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
auto constraintTypeInst = genericParamInst->mTypeConstraint->ToTypeInstance();
if ((constraintTypeInst != NULL) && (constraintTypeInst->IsInstanceOf(mCompiler->mEnumTypeDef)) && (explicitCast))
if ((constraintTypeInst != NULL) && (constraintTypeInst->IsDelegateOrFunction()))
{
// Enum->int
if ((explicitCast) && (toType->IsInteger()))
return typedVal.mValue;
// Could be a methodref - can't cast to anything else
}
BfTypedValue fromTypedValue;
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
fromTypedValue = GetDefaultTypedValue(genericParamInst->mTypeConstraint, false, BfDefaultValueKind_Undef);
else
fromTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), genericParamInst->mTypeConstraint, genericParamInst->mTypeConstraint->IsValueType());
auto result = CastToValue(srcNode, fromTypedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
if (result)
{
if ((genericParamInst->mTypeConstraint->IsDelegate()) && (toType->IsDelegate()))
if ((constraintTypeInst != NULL) && (constraintTypeInst->IsInstanceOf(mCompiler->mEnumTypeDef)) && (explicitCast))
{
// Don't allow cast when we are constrained by a delegate type, because BfMethodRefs can match and we require an actual alloc
Fail(StrFormat("Unable to cast '%s' to '%s' because delegate constraints allow valueless direct method references", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
return BfIRValue();
// Enum->int
if ((explicitCast) && (toType->IsInteger()))
return typedVal.mValue;
}
BfTypedValue fromTypedValue;
if (typedVal.mKind == BfTypedValueKind_GenericConstValue)
fromTypedValue = GetDefaultTypedValue(genericParamInst->mTypeConstraint, false, BfDefaultValueKind_Undef);
else
fromTypedValue = BfTypedValue(mBfIRBuilder->GetFakeVal(), genericParamInst->mTypeConstraint, genericParamInst->mTypeConstraint->IsValueType());
auto result = CastToValue(srcNode, fromTypedValue, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
if (result)
{
if ((genericParamInst->mTypeConstraint->IsDelegate()) && (toType->IsDelegate()))
{
// Don't allow cast when we are constrained by a delegate type, because BfMethodRefs can match and we require an actual alloc
Fail(StrFormat("Unable to cast '%s' to '%s' because delegate constraints allow valueless direct method references", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
return BfIRValue();
}
return result;
}
return result;
}
}
@ -11755,7 +11811,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
if (allowCast)
{
if (ignoreWrites)
if ((ignoreWrites) && (!typedVal.mValue.IsConst()))
return mBfIRBuilder->GetFakeVal();
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
}

View file

@ -2447,10 +2447,9 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
mTokenEnd = mSrcIdx;
return;
}
bool wasNeg = false;
bool hadOverflow = false;
int64 val = 0;
uint64 val = 0;
int numberBase = 10;
int expVal = 0;
int expSign = 0;
@ -2460,8 +2459,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
int hexDigits = 0;
if (c == '-')
{
wasNeg = true; //TODO: This never actually gets set any more (eaten as BfToken_Minus above). Move checks that use this to later in pipeline, then remove this
c = mSrc[mSrcIdx++];
BF_FATAL("Parsing error");
}
val = c - '0';
@ -2641,7 +2639,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
// This is actually a integer followed by an Int32 call (like 123.ToString)
mSrcIdx -= 2;
mTokenEnd = mSrcIdx;
mLiteral.mInt64 = val;
mLiteral.mUInt64 = val;
mLiteral.mTypeCode = BfTypeCode_IntUnknown;
mSyntaxToken = BfSyntaxToken_Literal;
return;
@ -2668,27 +2666,24 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
if (endNumber)
{
mTokenEnd = mSrcIdx - 1;
mSrcIdx--;
if (wasNeg)
val = -val;
mSrcIdx--;
if ((numberBase == 0x10) &&
((hexDigits >= 16) || ((hadSeps) && (hexDigits > 8)) || ((hadLeadingHexSep) && (hexDigits == 8))))
{
if (hexDigits > 16)
mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
mLiteral.mInt64 = val;
if ((val < 0) && (!wasNeg))
mLiteral.mUInt64 = val;
if (val >= 0x8000000000000000)
mLiteral.mTypeCode = BfTypeCode_UInt64;
else
mLiteral.mTypeCode = BfTypeCode_Int64;
}
else
{
mLiteral.mInt64 = val;
mLiteral.mUInt64 = val;
mLiteral.mTypeCode = BfTypeCode_IntUnknown;
if ((numberBase == 0x10) && (hexDigits == 7))
mLiteral.mWarnType = BfWarning_BF4201_Only7Hex;
if ((numberBase == 0x10) && (hexDigits == 9))
@ -2699,7 +2694,12 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
mPassInstance->FailAt("Value doesn't fit into int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
mLiteral.mTypeCode = BfTypeCode_Int64;
}
else if ((val < -0x80000000LL) || (val > 0xFFFFFFFFLL))
//else if ((val < -0x80000000LL) || (val > 0xFFFFFFFFLL))
else if (val >= 0x8000000000000000)
{
mLiteral.mTypeCode = BfTypeCode_UInt64;
}
else if (val > 0xFFFFFFFFLL)
{
mLiteral.mTypeCode = BfTypeCode_Int64;
}
@ -2709,7 +2709,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
return;
}
int64 prevVal = val;
uint64 prevVal = val;
if ((c >= '0') && (c <= '9') && (c < '0' + numberBase))
{
if (numberBase == 0x10)
@ -2731,9 +2731,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
}
else if ((c == 'u') || (c == 'U'))
{
if (wasNeg)
val = -val;
{
if ((mSrc[mSrcIdx] == 'l') || (mSrc[mSrcIdx] == 'L'))
{
if (mSrc[mSrcIdx] == 'l')
@ -2744,7 +2742,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
mLiteral.mUInt64 = (uint64)val;
if (hexDigits > 16)
mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
else if ((hadOverflow) || (wasNeg))
else if (hadOverflow)
mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
mSyntaxToken = BfSyntaxToken_Literal;
return;
@ -2752,7 +2750,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
mTokenEnd = mSrcIdx;
mLiteral.mTypeCode = BfTypeCode_UIntPtr;
mLiteral.mUInt32 = (uint32)val;
if ((hadOverflow) || (wasNeg) || ((uint64)val != (uint64)mLiteral.mUInt32))
if ((hadOverflow) || ((uint64)val != (uint64)mLiteral.mUInt32))
mPassInstance->FailAt("Value doesn't fit into uint32", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
mSyntaxToken = BfSyntaxToken_Literal;
return;
@ -2760,9 +2758,7 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
else if ((c == 'l') || (c == 'L'))
{
if (c == 'l')
TokenFail("Uppercase 'L' required for int64");
if (wasNeg)
val = -val;
TokenFail("Uppercase 'L' required for int64");
if ((mSrc[mSrcIdx] == 'u') || (mSrc[mSrcIdx] == 'U'))
{
mSrcIdx++;
@ -2771,25 +2767,24 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
mLiteral.mUInt64 = (uint64)val;
if (hexDigits > 16)
mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
else if ((hadOverflow) || (wasNeg))
else if (hadOverflow)
mPassInstance->FailAt("Value doesn't fit into uint64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
mSyntaxToken = BfSyntaxToken_Literal;
return;
}
}
mTokenEnd = mSrcIdx;
mLiteral.mTypeCode = BfTypeCode_Int64;
mLiteral.mInt64 = (int64)val;
bool signMatched = true;
if (val != 0)
signMatched = (val < 0) == wasNeg;
if (val == 0x8000000000000000)
mLiteral.mTypeCode = BfTypeCode_UInt64;
else if (val >= 0x8000000000000000)
hadOverflow = true;
if (numberBase == 0x10)
{
if (hexDigits > 16)
mPassInstance->FailAt("Too many hex digits for int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
}
else if ((hadOverflow) || (!signMatched))
else if (hadOverflow)
mPassInstance->FailAt("Value doesn't fit into int64", mSourceData, mTokenStart, mSrcIdx - mTokenStart);
mSyntaxToken = BfSyntaxToken_Literal;
return;
@ -2813,17 +2808,14 @@ void BfParser::NextToken(int endIdx, bool outerIsInterpolate)
else
{
mTokenEnd = mSrcIdx - 1;
mSrcIdx--;
if (wasNeg)
val = -val;
mLiteral.mInt64 = val;
mSrcIdx--;
mLiteral.mUInt64 = val;
mLiteral.mTypeCode = BfTypeCode_IntUnknown;
mSyntaxToken = BfSyntaxToken_Literal;
TokenFail("Unexpected character while parsing number", 0);
return;
}
//if ((val < 0) && (val != -0x8000000000000000))
if ((uint64)prevVal > (uint64)val)
hadOverflow = true;
}

View file

@ -226,6 +226,7 @@ public:
void SetSource(const char* data, int length);
void MoveSource(const char* data, int length); // Takes ownership of data ptr
void RefSource(const char* data, int length);
void MakeNegative(uint64& val, bool& hadOverflow);
void NextToken(int endIdx = -1, bool outerIsInterpolate = false);
BfAstNode* CreateNode();

View file

@ -300,6 +300,11 @@ int BfPrinter::CalcOrigLineSpacing(BfAstNode* bfAstNode, int* lineStartIdx)
void BfPrinter::WriteIgnoredNode(BfAstNode* node)
{
if ((!mOutString.IsEmpty()) && (!isspace((uint8)mOutString[mOutString.mLength - 1])))
{
Write(" ");
}
bool wasExpectingNewLine = mExpectingNewLine;
mTriviaIdx = std::max(mTriviaIdx, node->GetTriviaStart());
@ -1759,9 +1764,14 @@ void BfPrinter::Visit(BfLambdaBindExpression* lambdaBindExpr)
else
{
ExpectSpace();
VisitChild(lambdaBindExpr->mBody);
VisitChild(lambdaBindExpr->mBody);
}
}
}
VisitChild(lambdaBindExpr->mDtor);
mNextStateModify.mExpectingSpace = false;
mVirtualNewLineIdx = mNextStateModify.mWantNewLineIdx;
mCurIndentLevel = mNextStateModify.mWantVirtualIndent;
mVirtualIndentLevel = mNextStateModify.mWantVirtualIndent;
}
void BfPrinter::Visit(BfObjectCreateExpression* newExpr)
@ -2643,7 +2653,7 @@ void BfPrinter::Visit(BfIndexerDeclaration* indexerDeclaration)
}
void BfPrinter::Visit(BfFieldDeclaration* fieldDeclaration)
{
{
bool isEnumDecl = false;
if (auto enumEntry = BfNodeDynCast<BfEnumEntryDeclaration>(fieldDeclaration))
@ -2703,18 +2713,10 @@ void BfPrinter::Visit(BfFieldDeclaration* fieldDeclaration)
QueueVisitChild(fieldDeclaration->mInitializer);
}
auto fieldDtor = fieldDeclaration->mFieldDtor;
while (fieldDtor != NULL)
{
ExpectSpace();
QueueVisitChild(fieldDtor->mTildeToken);
ExpectSpace();
QueueVisitChild(fieldDtor->mBody);
fieldDtor = fieldDtor->mNextFieldDtor;
}
mNextStateModify.mExpectingSpace = false;
FlushVisitChild();
VisitChild(fieldDeclaration->mFieldDtor);
mNextStateModify.mExpectingSpace = false;
}
void BfPrinter::Visit(BfEnumCaseDeclaration* enumCaseDeclaration)
@ -2763,6 +2765,32 @@ void BfPrinter::Visit(BfTypeAliasDeclaration* typeDeclaration)
VisitChild(typeDeclaration->mEndSemicolon);
}
void BfPrinter::Visit(BfFieldDtorDeclaration* fieldDtorDeclaration)
{
ExpectSpace();
if (fieldDtorDeclaration->mBody != NULL)
{
if (fieldDtorDeclaration->mBody->IsA<BfBlock>())
{
ExpectNewLine();
ExpectIndent();
VisitChild(fieldDtorDeclaration->mTildeToken);
VisitChild(fieldDtorDeclaration->mBody);
ExpectUnindent();
}
else
{
VisitChild(fieldDtorDeclaration->mTildeToken);
ExpectSpace();
VisitChild(fieldDtorDeclaration->mBody);
}
}
else
VisitChild(fieldDtorDeclaration->mTildeToken);
VisitChild(fieldDtorDeclaration->mNextFieldDtor);
}
void BfPrinter::Visit(BfTypeDeclaration* typeDeclaration)
{
SetAndRestoreValue<BfTypeDeclaration*> prevTypeDecl(mCurTypeDecl, typeDeclaration);

View file

@ -220,6 +220,7 @@ public:
virtual void Visit(BfFieldDeclaration* fieldDeclaration) override;
virtual void Visit(BfEnumCaseDeclaration* enumCaseDeclaration) override;
virtual void Visit(BfTypeAliasDeclaration* typeDeclaration) override;
virtual void Visit(BfFieldDtorDeclaration* fieldDtorDeclaration) override;
virtual void Visit(BfTypeDeclaration* typeDeclaration) override;
virtual void Visit(BfUsingDirective* usingDirective) override;
virtual void Visit(BfUsingModDirective* usingDirective) override;

View file

@ -5912,12 +5912,9 @@ BfAstNode* BfReducer::ReadTypeMember(BfTokenNode* tokenNode, bool declStarted, i
ReplaceNode(tokenNode, operatorDecl);
operatorDecl->mOperatorToken = tokenNode;
auto nextIdentifier = ExpectIdentifierAfter(operatorDecl, "type");
if (nextIdentifier == NULL)
return operatorDecl;
mVisitorPos.mReadPos--; // Backtrack, that's part of our type
auto typeRef = CreateTypeRefAfter(operatorDecl);
if (typeRef == NULL)
return operatorDecl;
MEMBER_SET_CHECKED(operatorDecl, mReturnType, typeRef);
operatorDecl->mIsConvOperator = true;

View file

@ -1298,15 +1298,6 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
}
}
// if ((paramIdx == 0) && (GetParamName(0) == "this") && (checkType->IsPointer()))
// {
// // We don't actually pass a this pointer for mut methods in valueless structs
// auto underlyingType = checkType->GetUnderlyingType();
// module->PopulateType(underlyingType, BfPopulateType_Data);
// if (underlyingType->IsValuelessType())
// continue;
// }
if (checkType->CanBeValuelessType())
module->PopulateType(checkType, BfPopulateType_Data);
if ((checkType->IsValuelessType()) && (!checkType->IsMethodRef()))
@ -1563,6 +1554,7 @@ BfTypeInstance::~BfTypeInstance()
if ((mTypeDef != NULL) && (mTypeDef->mEmitParent != NULL))
{
mMethodInstanceGroups.Clear();
BfLogSys(mModule->mSystem, "Type %p dtor deleting typeDef %p\n", this, mTypeDef);
delete mTypeDef;
}
}
@ -2636,6 +2628,12 @@ void BfTupleType::Finish()
//////////////////////////////////////////////////////////////////////////
BfBoxedType::~BfBoxedType()
{
if ((mTypeDef != NULL) && (mTypeDef->mEmitParent != NULL))
mTypeDef = NULL;
}
BfType* BfBoxedType::GetModifiedElementType()
{
if ((mBoxedFlags & BoxedFlags_StructPtr) != 0)

View file

@ -61,7 +61,8 @@ enum BfMethodNameFlags : uint8
BfMethodNameFlag_ResolveGenericParamNames = 1,
BfMethodNameFlag_OmitTypeName = 2,
BfMethodNameFlag_IncludeReturnType = 4,
BfMethodNameFlag_OmitParams = 8
BfMethodNameFlag_OmitParams = 8,
BfMethodNameFlag_IncludeMut = 0x10
};
enum BfGetMethodInstanceFlags : uint16
@ -1827,6 +1828,7 @@ class BfCeTypeInfo
public:
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
Array<int> mPendingInterfaces;
Val128 mHash;
bool mFailed;
BfCeTypeInfo* mNext;
@ -2109,6 +2111,7 @@ public:
mBoxedBaseType = NULL;
mBoxedFlags = BoxedFlags_None;
}
~BfBoxedType();
virtual bool IsBoxed() override { return true; }

View file

@ -793,11 +793,6 @@ BfTypeDef::~BfTypeDef()
{
BfLogSysM("BfTypeDef::~BfTypeDef %p\n", this);
if ((mHash == -1330357811) && (IsEmitted()))
{
NOP;
}
delete mNextRevision;
FreeMembers();
@ -2282,6 +2277,41 @@ bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, int64 value)
return false;
}
bool BfSystem::DoesLiteralFit(BfTypeCode typeCode, uint64 value)
{
if (typeCode == BfTypeCode_IntPtr)
typeCode = (mPtrSize == 4) ? BfTypeCode_Int32 : BfTypeCode_Int64;
if (typeCode == BfTypeCode_UIntPtr)
typeCode = (mPtrSize == 4) ? BfTypeCode_UInt32 : BfTypeCode_UInt64;
if (value >= 0x8000000000000000)
return typeCode == BfTypeCode_UInt64;
switch (typeCode)
{
case BfTypeCode_Int8:
return (value < 0x80);
case BfTypeCode_Int16:
return (value < 0x8000);
case BfTypeCode_Int32:
return (value < 0x80000000LL);
case BfTypeCode_Int64:
return true;
case BfTypeCode_UInt8:
return (value < 0x100);
case BfTypeCode_UInt16:
return (value < 0x10000);
case BfTypeCode_UInt32:
return (value < 0x100000000LL);
case BfTypeCode_UInt64:
return true;
default: break;
}
return false;
}
BfParser* BfSystem::CreateParser(BfProject* bfProject)
{
AutoCrit crit(mDataLock);
@ -3693,10 +3723,14 @@ void BfSystem::RemoveOldData()
{
AutoCrit autoCrit(mDataLock);
for (auto typeDef : mTypeDefDeleteQueue)
for (int i = 0; i < (int)mTypeDefDeleteQueue.size(); i++)
{
auto typeDef = mTypeDefDeleteQueue[i];
mTypeDefDeleteQueue[i] = NULL;
BfLogSys(this, "RemoveOldData deleting from mTypeDefDeleteQueue %p\n", typeDef);
delete typeDef;
}
mTypeDefDeleteQueue.Clear();
if (!mProjectDeleteQueue.IsEmpty())
{
@ -3729,6 +3763,7 @@ void BfSystem::RemoveOldData()
void BfSystem::VerifyTypeDef(BfTypeDef* typeDef)
{
#if defined _DEBUG && false
auto _FindTypeDef = [&](BfTypeReference* typeRef)
{
if (auto directStrTypeRef = BfNodeDynCast<BfDirectStrTypeReference>(typeRef))
@ -3762,6 +3797,7 @@ void BfSystem::VerifyTypeDef(BfTypeDef* typeDef)
_FindTypeDef(paramDef->mTypeRef);
}
}
#endif
}
BfTypeOptions* BfSystem::GetTypeOptions(int optionsIdx)

View file

@ -1610,6 +1610,7 @@ public:
void CreateBasicTypes();
bool DoesLiteralFit(BfTypeCode typeCode, int64 value);
bool DoesLiteralFit(BfTypeCode typeCode, uint64 value);
BfParser* CreateParser(BfProject* bfProject);
BfCompiler* CreateCompiler(bool isResolveOnly);
BfProject* GetProject(const StringImpl& projName);

View file

@ -1288,7 +1288,7 @@ void CeBuilder::Build()
auto methodInstance = mCeFunction->mMethodInstance;
if (methodInstance != NULL)
{
{
BfMethodInstance dupMethodInstance;
dupMethodInstance.CopyFrom(methodInstance);
auto methodDef = methodInstance->mMethodDef;
@ -1638,10 +1638,10 @@ void CeBuilder::Build()
EmitBinaryOp(CeOp_Shl_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
break;
case BeBinaryOpKind_RightShift:
EmitBinaryOp(CeOp_Shr_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
EmitBinaryOp(CeOp_Shr_U8, CeOp_InvalidOp, ceLHS, ceRHS, result);
break;
case BeBinaryOpKind_ARightShift:
EmitBinaryOp(CeOp_Shr_U8, CeOp_InvalidOp, ceLHS, ceRHS, result);
EmitBinaryOp(CeOp_Shr_I8, CeOp_InvalidOp, ceLHS, ceRHS, result);
break;
default:
Fail("Invalid binary op");
@ -2476,7 +2476,18 @@ void CeBuilder::Build()
EmitFrameOffset(ceSize);
}
break;
case BfIRIntrinsic_MemSet:
{
CeOperand ceDestPtr = GetOperand(castedInst->mArgs[0].mValue);
CeOperand ceValue = GetOperand(castedInst->mArgs[1].mValue);
CeOperand ceSize = GetOperand(castedInst->mArgs[2].mValue);
Emit(CeOp_MemSet);
EmitFrameOffset(ceDestPtr);
EmitFrameOffset(ceValue);
EmitFrameOffset(ceSize);
}
break;
case BfIRIntrinsic_AtomicFence:
// Nothing to do
@ -4729,6 +4740,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
return false;
}
}
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitAddInterface)
{
int32 typeId = *(int32*)((uint8*)stackPtr);
int32 ifaceTypeId = *(int32*)((uint8*)stackPtr + sizeof(int32));
if ((mCurEmitContext == NULL) || (mCurEmitContext->mType->mTypeId != typeId))
{
_Fail("Code cannot be emitted for this type in this context");
return false;
}
mCurEmitContext->mInterfaces.Add(ifaceTypeId);
}
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodEntry)
{
int64 methodHandle = *(int64*)((uint8*)stackPtr);
@ -4972,7 +4994,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
if (*fastFinishPtr)
{
if (*cancelingPtr)
_Fail("Comptime evaluation canceled");
{
if ((mCurModule != NULL) && (mCurModule->mCurTypeInstance != NULL))
mCurModule->DeferRebuildType(mCurModule->mCurTypeInstance);
else
_Fail("Comptime evaluation canceled");
}
return false;
}
@ -6817,6 +6844,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
{
ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody;
}
if (methodDef->mName == "Comptime_EmitAddInterface")
{
ceFunction->mFunctionKind = CeFunctionKind_EmitAddInterface;
}
else if (methodDef->mName == "Comptime_EmitMethodEntry")
{
ceFunction->mFunctionKind = CeFunctionKind_EmitMethodEntry;

View file

@ -289,6 +289,7 @@ enum CeFunctionKind
CeFunctionKind_Method_GetParamInfo,
CeFunctionKind_EmitTypeBody,
CeFunctionKind_EmitAddInterface,
CeFunctionKind_EmitMethodEntry,
CeFunctionKind_EmitMethodExit,
CeFunctionKind_EmitMixin,
@ -687,6 +688,7 @@ class CeEmitContext
public:
BfType* mType;
BfMethodInstance* mMethodInstance;
Array<int32> mInterfaces;
String mEmitData;
String mExitEmitData;
bool mFailed;
@ -697,6 +699,11 @@ public:
mMethodInstance = NULL;
mFailed = false;
}
bool HasEmissions()
{
return !mEmitData.IsEmpty() || !mInterfaces.IsEmpty();
}
};
class CeContext