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:
parent
c2c7431620
commit
b70745ef1e
48 changed files with 2975 additions and 918 deletions
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1633,6 +1633,7 @@ public:
|
|||
bool IsTargetingBeefBackend();
|
||||
bool WantsLifetimes();
|
||||
bool HasCompiledOutput();
|
||||
bool HasExecutedOutput();
|
||||
void SkipObjectAccessCheck(BfTypedValue typedVal);
|
||||
void EmitObjectAccessCheck(BfTypedValue typedVal);
|
||||
void EmitEnsureInstructionAt();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue