mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Early code generation support
This commit is contained in:
parent
0b48a60592
commit
71d4dd0e90
26 changed files with 2422 additions and 1576 deletions
|
@ -274,6 +274,21 @@ namespace System
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Method)]
|
||||||
|
struct OnCompileAttribute : Attribute
|
||||||
|
{
|
||||||
|
public enum Kind
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
TypeInit,
|
||||||
|
TypeDone
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(Kind kind)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[AttributeUsage(.Method)]
|
[AttributeUsage(.Method)]
|
||||||
public struct ComptimeAttribute : Attribute
|
public struct ComptimeAttribute : Attribute
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,21 +1,6 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
[AttributeUsage(.Method)]
|
|
||||||
struct OnCompileAttribute : Attribute
|
|
||||||
{
|
|
||||||
public enum Kind
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
TypeInit,
|
|
||||||
TypeDone
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Kind kind)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class Compiler
|
static class Compiler
|
||||||
{
|
{
|
||||||
public struct MethodBuilder
|
public struct MethodBuilder
|
||||||
|
|
|
@ -7,9 +7,33 @@ namespace System.Reflection
|
||||||
*((*(T2**)&data)++)
|
*((*(T2**)&data)++)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool HasCustomAttribute(void* inAttrData, Type attributeType)
|
||||||
|
{
|
||||||
|
TypeId findTypeId = attributeType.[Friend]mTypeId;
|
||||||
|
|
||||||
|
void* data = inAttrData;
|
||||||
|
data++;
|
||||||
|
|
||||||
|
uint8 count = Decode!<uint8>(data);
|
||||||
|
for (int32 attrIdx = 0; attrIdx < count; attrIdx++)
|
||||||
|
AttrBlock:
|
||||||
|
{
|
||||||
|
void* startPtr = data;
|
||||||
|
var len = Decode!<uint16>(data);
|
||||||
|
void* endPtr = (uint8*)startPtr + len;
|
||||||
|
|
||||||
|
var typeId = Decode!<TypeId>(data);
|
||||||
|
if (typeId == findTypeId)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
data = endPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public static Result<void> GetCustomAttribute(void* inAttrData, Type attributeType, Object targetAttr)
|
public static Result<void> GetCustomAttribute(void* inAttrData, Type attributeType, Object targetAttr)
|
||||||
{
|
{
|
||||||
|
|
||||||
TypeId findTypeId = attributeType.[Friend]mTypeId;
|
TypeId findTypeId = attributeType.[Friend]mTypeId;
|
||||||
|
|
||||||
void* data = inAttrData;
|
void* data = inAttrData;
|
||||||
|
|
|
@ -472,6 +472,9 @@ namespace System
|
||||||
}
|
}
|
||||||
|
|
||||||
static extern Type Comptime_GetTypeById(int32 typeId);
|
static extern Type Comptime_GetTypeById(int32 typeId);
|
||||||
|
static extern Type Comptime_GetTypeByName(StringView name);
|
||||||
|
static extern Type Comptime_GetSpecializedType(Type unspecializedType, Span<Type> typeArgs);
|
||||||
|
static extern bool Comptime_Type_GetCustomAttribute(int32 typeId, int32 attributeId, void* dataPtr);
|
||||||
|
|
||||||
protected static Type GetType(TypeId typeId)
|
protected static Type GetType(TypeId typeId)
|
||||||
{
|
{
|
||||||
|
@ -487,6 +490,19 @@ namespace System
|
||||||
return sTypes[typeId];
|
return sTypes[typeId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Result<Type> GetTypeByName(StringView typeName)
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
var type = Comptime_GetTypeByName(typeName);
|
||||||
|
if (type == null)
|
||||||
|
return .Err;
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
void GetBasicName(String strBuffer)
|
void GetBasicName(String strBuffer)
|
||||||
{
|
{
|
||||||
switch (mTypeCode)
|
switch (mTypeCode)
|
||||||
|
@ -557,8 +573,28 @@ namespace System
|
||||||
return FieldInfo.Enumerator(null, bindingFlags);
|
return FieldInfo.Enumerator(null, bindingFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasCustomAttribute<T>() where T : Attribute
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
return Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (var typeInstance = this as TypeInstance)
|
||||||
|
return typeInstance.[Friend]HasCustomAttribute<T>(typeInstance.[Friend]mCustomAttributesIdx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public Result<T> GetCustomAttribute<T>() where T : Attribute
|
public Result<T> GetCustomAttribute<T>() where T : Attribute
|
||||||
{
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
T val = ?;
|
||||||
|
if (Comptime_Type_GetCustomAttribute((int32)TypeId, typeof(T).TypeId, &val))
|
||||||
|
return val;
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
if (var typeInstance = this as TypeInstance)
|
if (var typeInstance = this as TypeInstance)
|
||||||
return typeInstance.[Friend]GetCustomAttribute<T>(typeInstance.[Friend]mCustomAttributesIdx);
|
return typeInstance.[Friend]GetCustomAttribute<T>(typeInstance.[Friend]mCustomAttributesIdx);
|
||||||
return .Err;
|
return .Err;
|
||||||
|
@ -577,6 +613,9 @@ namespace System
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
Runtime.FatalError("Comptime type enumeration not supported");
|
||||||
|
|
||||||
if (mCurId >= sTypeCount)
|
if (mCurId >= sTypeCount)
|
||||||
return .Err;
|
return .Err;
|
||||||
let type = sTypes[mCurId++];
|
let type = sTypes[mCurId++];
|
||||||
|
@ -929,6 +968,15 @@ namespace System.Reflection
|
||||||
return FieldInfo.Enumerator(this, bindingFlags);
|
return FieldInfo.Enumerator(this, bindingFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool HasCustomAttribute<T>(int customAttributeIdx) where T : Attribute
|
||||||
|
{
|
||||||
|
if (customAttributeIdx == -1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
void* data = mCustomAttrDataPtr[customAttributeIdx];
|
||||||
|
return AttributeInfo.HasCustomAttribute(data, typeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
Result<T> GetCustomAttribute<T>(int customAttributeIdx) where T : Attribute
|
Result<T> GetCustomAttribute<T>(int customAttributeIdx) where T : Attribute
|
||||||
{
|
{
|
||||||
if (customAttributeIdx == -1)
|
if (customAttributeIdx == -1)
|
||||||
|
@ -1043,6 +1091,17 @@ namespace System.Reflection
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 mGenericParamCount;
|
uint8 mGenericParamCount;
|
||||||
|
|
||||||
|
public Result<Type> GetSpecializedType(params Span<Type> typeArgs)
|
||||||
|
{
|
||||||
|
if (Compiler.IsComptime)
|
||||||
|
{
|
||||||
|
var specializedType = Type.[Friend]Comptime_GetSpecializedType(this, typeArgs);
|
||||||
|
if (specializedType != null)
|
||||||
|
return specializedType;
|
||||||
|
}
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only for resolved types
|
// Only for resolved types
|
||||||
|
|
|
@ -813,6 +813,25 @@ bool BfAstNode::LocationEndEquals(BfAstNode* otherNode)
|
||||||
(GetSrcEnd() == otherNode->GetSrcEnd());
|
(GetSrcEnd() == otherNode->GetSrcEnd());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String BfAstNode::LocationToString()
|
||||||
|
{
|
||||||
|
auto parserData = GetParserData();
|
||||||
|
if (parserData == NULL)
|
||||||
|
return String();
|
||||||
|
|
||||||
|
String loc;
|
||||||
|
|
||||||
|
int line = -1;
|
||||||
|
int lineChar = -1;
|
||||||
|
parserData->GetLineCharAtIdx(mSrcStart, line, lineChar);
|
||||||
|
if (line != -1)
|
||||||
|
loc += StrFormat("at line %d:%d", line + 1, lineChar + 1);
|
||||||
|
loc += " in ";
|
||||||
|
loc += parserData->mFileName;
|
||||||
|
|
||||||
|
return loc;
|
||||||
|
}
|
||||||
|
|
||||||
void BfAstNode::Add(BfAstNode* bfAstNode)
|
void BfAstNode::Add(BfAstNode* bfAstNode)
|
||||||
{
|
{
|
||||||
#ifdef BF_AST_HAS_PARENT_MEMBER
|
#ifdef BF_AST_HAS_PARENT_MEMBER
|
||||||
|
|
|
@ -1101,6 +1101,7 @@ public:
|
||||||
static void ClassAccept(BfAstNode* node, BfStructuralVisitor* bfVisitor) { bfVisitor->Visit(node); }
|
static void ClassAccept(BfAstNode* node, BfStructuralVisitor* bfVisitor) { bfVisitor->Visit(node); }
|
||||||
bool LocationEquals(BfAstNode* otherNode);
|
bool LocationEquals(BfAstNode* otherNode);
|
||||||
bool LocationEndEquals(BfAstNode* otherNode);
|
bool LocationEndEquals(BfAstNode* otherNode);
|
||||||
|
String LocationToString();
|
||||||
void Add(BfAstNode* bfAstNode);
|
void Add(BfAstNode* bfAstNode);
|
||||||
bool IsMissingSemicolon();
|
bool IsMissingSemicolon();
|
||||||
bool IsExpression();
|
bool IsExpression();
|
||||||
|
|
|
@ -8574,8 +8574,6 @@ int BfCompiler::GetEmitSource(const StringImpl& fileName, StringImpl* outBuffer)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
String typeIdStr = fileName.Substring(lastDollarPos + 1, dotPos - lastDollarPos - 1);
|
String typeIdStr = fileName.Substring(lastDollarPos + 1, dotPos - lastDollarPos - 1);
|
||||||
|
|
||||||
int revisionId = (int)atoi(typeIdStr.c_str());
|
|
||||||
int typeId = (int)atoi(typeIdStr.c_str());
|
int typeId = (int)atoi(typeIdStr.c_str());
|
||||||
if ((typeId <= 0) || (typeId >= mContext->mTypes.mSize))
|
if ((typeId <= 0) || (typeId >= mContext->mTypes.mSize))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -8786,7 +8784,9 @@ BF_EXPORT int BF_CALLTYPE BfCompiler_GetCurConstEvalExecuteId(BfCompiler* bfComp
|
||||||
{
|
{
|
||||||
if (bfCompiler->mCEMachine == NULL)
|
if (bfCompiler->mCEMachine == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
if (bfCompiler->mCEMachine->mCurMethodInstance == NULL)
|
if (bfCompiler->mCEMachine->mCurContext == NULL)
|
||||||
|
return -1;
|
||||||
|
if (bfCompiler->mCEMachine->mCurContext->mCurMethodInstance == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
return bfCompiler->mCEMachine->mExecuteId;
|
return bfCompiler->mCEMachine->mExecuteId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,6 +366,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mModule->PreFail())
|
||||||
mModule->Fail(StrFormat("Not enough parameters specified. Expected %d fewer.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
|
mModule->Fail(StrFormat("Not enough parameters specified. Expected %d fewer.", methodInstance->GetParamCount() - (int)arguments.size()), refNode);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ public:
|
||||||
ResolveKind_ResolvingVarType,
|
ResolveKind_ResolvingVarType,
|
||||||
ResolveKind_UnionInnerType,
|
ResolveKind_UnionInnerType,
|
||||||
ResolveKind_LocalVariable,
|
ResolveKind_LocalVariable,
|
||||||
|
ResolveKind_Attributes
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -61,6 +61,7 @@ BfDefBuilder::BfDefBuilder(BfSystem* bfSystem)
|
||||||
mCurTypeDef = NULL;
|
mCurTypeDef = NULL;
|
||||||
mCurActualTypeDef = NULL;
|
mCurActualTypeDef = NULL;
|
||||||
mFullRefresh = false;
|
mFullRefresh = false;
|
||||||
|
mIsComptime = false;
|
||||||
mResolvePassData = NULL;
|
mResolvePassData = NULL;
|
||||||
mCurSource = NULL;
|
mCurSource = NULL;
|
||||||
|
|
||||||
|
@ -1184,7 +1185,7 @@ BfFieldDef* BfDefBuilder::AddField(BfTypeDef* typeDef, BfTypeReference* fieldTyp
|
||||||
return fieldDef;
|
return fieldDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
BfMethodDef* BfDefBuilder::AddMethod(BfTypeDef* typeDef, BfMethodType methodType, BfProtection protection, bool isStatic, const StringImpl& name)
|
BfMethodDef* BfDefBuilder::AddMethod(BfTypeDef* typeDef, BfMethodType methodType, BfProtection protection, bool isStatic, const StringImpl& name, bool addedAfterEmit)
|
||||||
{
|
{
|
||||||
BF_ASSERT(typeDef->mTypeCode != BfTypeCode_TypeAlias);
|
BF_ASSERT(typeDef->mTypeCode != BfTypeCode_TypeAlias);
|
||||||
|
|
||||||
|
@ -1193,6 +1194,7 @@ BfMethodDef* BfDefBuilder::AddMethod(BfTypeDef* typeDef, BfMethodType methodType
|
||||||
typeDef->mMethods.push_back(methodDef);
|
typeDef->mMethods.push_back(methodDef);
|
||||||
methodDef->mDeclaringType = typeDef;
|
methodDef->mDeclaringType = typeDef;
|
||||||
methodDef->mMethodType = methodType;
|
methodDef->mMethodType = methodType;
|
||||||
|
methodDef->mAddedAfterEmit = addedAfterEmit;
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
{
|
{
|
||||||
if (methodType == BfMethodType_Ctor)
|
if (methodType == BfMethodType_Ctor)
|
||||||
|
@ -1364,6 +1366,12 @@ BfTypeDef* BfDefBuilder::ComparePrevTypeDef(BfTypeDef* prevTypeDef, BfTypeDef* c
|
||||||
|
|
||||||
void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
void BfDefBuilder::Visit(BfTypeDeclaration* typeDeclaration)
|
||||||
{
|
{
|
||||||
|
if (typeDeclaration->IsEmitted())
|
||||||
|
{
|
||||||
|
Fail("Type declarations are not allowed in emitted code", typeDeclaration);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData);
|
BF_ASSERT(typeDeclaration->GetSourceData() == mCurSource->mSourceData);
|
||||||
|
|
||||||
if ((typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mNameNode == NULL))
|
if ((typeDeclaration->mTypeNode != NULL) && (typeDeclaration->mNameNode == NULL))
|
||||||
|
@ -1999,6 +2007,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mReturnTypeRef = mSystem->mDirectIntTypeRef;
|
methodDef->mReturnTypeRef = mSystem->mDirectIntTypeRef;
|
||||||
methodDef->mIsStatic = true;
|
methodDef->mIsStatic = true;
|
||||||
methodDef->mBody = method->mBody;
|
methodDef->mBody = method->mBody;
|
||||||
|
methodDef->mAddedAfterEmit = mIsComptime;
|
||||||
|
|
||||||
for (auto param : method->mParams)
|
for (auto param : method->mParams)
|
||||||
{
|
{
|
||||||
|
@ -2158,24 +2167,24 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
|
|
||||||
if ((mCurTypeDef->mTypeCode == BfTypeCode_Object) && (!mCurTypeDef->mIsStatic) && (ctorClear == NULL))
|
if ((mCurTypeDef->mTypeCode == BfTypeCode_Object) && (!mCurTypeDef->mIsStatic) && (ctorClear == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_CtorClear, BfProtection_Private, false, "", mIsComptime);
|
||||||
methodDef->mIsMutating = true;
|
methodDef->mIsMutating = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsDtor) && (dtor == NULL))
|
if ((needsDtor) && (dtor == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, false, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, false, "", mIsComptime);
|
||||||
BF_ASSERT(mCurTypeDef->mDtorDef == methodDef);
|
BF_ASSERT(mCurTypeDef->mDtorDef == methodDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsStaticDtor) && (staticDtor == NULL))
|
if ((needsStaticDtor) && (staticDtor == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, true, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Dtor, BfProtection_Public, true, "", mIsComptime);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsStaticInit) && (staticCtor == NULL))
|
if ((needsStaticInit) && (staticCtor == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, BfProtection_Public, true, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, BfProtection_Public, true, "", mIsComptime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool makeCtorPrivate = hasCtor;
|
bool makeCtorPrivate = hasCtor;
|
||||||
|
@ -2193,7 +2202,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
|
|
||||||
// Create default constructor. If it's the only constructor then make it public,
|
// Create default constructor. If it's the only constructor then make it public,
|
||||||
// otherwise make it private so we can still internally use it but the user can't
|
// otherwise make it private so we can still internally use it but the user can't
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, prot, false, "");
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Ctor, prot, false, "", mIsComptime);
|
||||||
methodDef->mIsMutating = true;
|
methodDef->mIsMutating = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2229,19 +2238,19 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
{
|
{
|
||||||
if ((hasStaticField) && (staticMarkMethod == NULL))
|
if ((hasStaticField) && (staticMarkMethod == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_MARKMEMBERS_STATIC, mIsComptime);
|
||||||
methodDef->mIsNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasThreadStatics)
|
if (hasThreadStatics)
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_FIND_TLS_MEMBERS);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, true, BF_METHODNAME_FIND_TLS_MEMBERS, mIsComptime);
|
||||||
methodDef->mIsNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((hasNonStaticField) && (markMethod == NULL))
|
if ((hasNonStaticField) && (markMethod == NULL))
|
||||||
{
|
{
|
||||||
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS);
|
auto methodDef = AddMethod(mCurTypeDef, BfMethodType_Normal, BfProtection_Protected, false, BF_METHODNAME_MARKMEMBERS, mIsComptime);
|
||||||
methodDef->mIsVirtual = true;
|
methodDef->mIsVirtual = true;
|
||||||
methodDef->mIsOverride = true;
|
methodDef->mIsOverride = true;
|
||||||
methodDef->mIsNoReflect = true;
|
methodDef->mIsNoReflect = true;
|
||||||
|
@ -2262,6 +2271,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mReturnTypeRef = mSystem->mDirectBoolTypeRef;
|
methodDef->mReturnTypeRef = mSystem->mDirectBoolTypeRef;
|
||||||
methodDef->mProtection = BfProtection_Public;
|
methodDef->mProtection = BfProtection_Public;
|
||||||
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "checkEnum");
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "checkEnum");
|
||||||
|
methodDef->mAddedAfterEmit = mIsComptime;
|
||||||
|
|
||||||
// Underlying
|
// Underlying
|
||||||
{
|
{
|
||||||
|
@ -2272,6 +2282,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mReturnTypeRef = mSystem->mDirectSelfBaseTypeRef;
|
methodDef->mReturnTypeRef = mSystem->mDirectSelfBaseTypeRef;
|
||||||
methodDef->mMethodType = BfMethodType_PropertyGetter;
|
methodDef->mMethodType = BfMethodType_PropertyGetter;
|
||||||
methodDef->mProtection = BfProtection_Public;
|
methodDef->mProtection = BfProtection_Public;
|
||||||
|
methodDef->mAddedAfterEmit = mIsComptime;
|
||||||
|
|
||||||
auto propDef = new BfPropertyDef();
|
auto propDef = new BfPropertyDef();
|
||||||
mCurTypeDef->mProperties.Add(propDef);
|
mCurTypeDef->mProperties.Add(propDef);
|
||||||
|
@ -2292,6 +2303,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mReturnTypeRef = mSystem->mDirectRefSelfBaseTypeRef;
|
methodDef->mReturnTypeRef = mSystem->mDirectRefSelfBaseTypeRef;
|
||||||
methodDef->mMethodType = BfMethodType_PropertyGetter;
|
methodDef->mMethodType = BfMethodType_PropertyGetter;
|
||||||
methodDef->mProtection = BfProtection_Public;
|
methodDef->mProtection = BfProtection_Public;
|
||||||
|
methodDef->mAddedAfterEmit = mIsComptime;
|
||||||
|
|
||||||
auto propDef = new BfPropertyDef();
|
auto propDef = new BfPropertyDef();
|
||||||
mCurTypeDef->mProperties.Add(propDef);
|
mCurTypeDef->mProperties.Add(propDef);
|
||||||
|
@ -2315,6 +2327,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mIsVirtual = true;
|
methodDef->mIsVirtual = true;
|
||||||
AddParam(methodDef, mSystem->mDirectStringTypeRef, "outStr");
|
AddParam(methodDef, mSystem->mDirectStringTypeRef, "outStr");
|
||||||
mCurTypeDef->mHasOverrideMethods = true;
|
mCurTypeDef->mHasOverrideMethods = true;
|
||||||
|
methodDef->mAddedAfterEmit = mIsComptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((needsEqualsMethod) && (equalsMethod == NULL))
|
if ((needsEqualsMethod) && (equalsMethod == NULL))
|
||||||
|
@ -2328,6 +2341,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mIsStatic = true;
|
methodDef->mIsStatic = true;
|
||||||
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs");
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs");
|
||||||
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
|
||||||
|
methodDef->mAddedAfterEmit = mIsComptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsEqualsMethod)
|
if (needsEqualsMethod)
|
||||||
|
@ -2341,6 +2355,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
||||||
methodDef->mIsStatic = true;
|
methodDef->mIsStatic = true;
|
||||||
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs");
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "lhs");
|
||||||
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
|
AddParam(methodDef, mSystem->mDirectSelfTypeRef, "rhs");
|
||||||
|
methodDef->mAddedAfterEmit = mIsComptime;
|
||||||
}
|
}
|
||||||
|
|
||||||
HashContext inlineHashCtx;
|
HashContext inlineHashCtx;
|
||||||
|
|
|
@ -18,6 +18,7 @@ public:
|
||||||
BfTypeDef* mCurTypeDef;
|
BfTypeDef* mCurTypeDef;
|
||||||
BfTypeDef* mCurActualTypeDef;
|
BfTypeDef* mCurActualTypeDef;
|
||||||
bool mFullRefresh;
|
bool mFullRefresh;
|
||||||
|
bool mIsComptime;
|
||||||
BfResolvePassData* mResolvePassData;
|
BfResolvePassData* mResolvePassData;
|
||||||
BfAtomComposite mNamespace;
|
BfAtomComposite mNamespace;
|
||||||
Array<BfAtomComposite> mNamespaceSearch;
|
Array<BfAtomComposite> mNamespaceSearch;
|
||||||
|
@ -33,7 +34,7 @@ public:
|
||||||
//static BfNamedTypeReference* AllocTypeReference(BfSource* bfSource, const StringImpl& typeName);
|
//static BfNamedTypeReference* AllocTypeReference(BfSource* bfSource, const StringImpl& typeName);
|
||||||
//static BfResolvedTypeReference* AllocTypeReference(BfSource* bfSource, BfType* type);
|
//static BfResolvedTypeReference* AllocTypeReference(BfSource* bfSource, BfType* type);
|
||||||
static BfFieldDef* AddField(BfTypeDef* typeDef, BfTypeReference* typeRef, const StringImpl& name);
|
static BfFieldDef* AddField(BfTypeDef* typeDef, BfTypeReference* typeRef, const StringImpl& name);
|
||||||
static BfMethodDef* AddMethod(BfTypeDef* typeDef, BfMethodType methodType, BfProtection protection, bool isStatic, const StringImpl& name);
|
static BfMethodDef* AddMethod(BfTypeDef* typeDef, BfMethodType methodType, BfProtection protection, bool isStatic, const StringImpl& name, bool addedAfterEmit = false);
|
||||||
static BfMethodDef* AddDtor(BfTypeDef* typeDef);
|
static BfMethodDef* AddDtor(BfTypeDef* typeDef);
|
||||||
static void AddDynamicCastMethods(BfTypeDef* typeDef);
|
static void AddDynamicCastMethods(BfTypeDef* typeDef);
|
||||||
void AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName);
|
void AddParam(BfMethodDef* methodDef, BfTypeReference* typeRef, const StringImpl& paramName);
|
||||||
|
|
|
@ -2092,6 +2092,8 @@ Done:
|
||||||
void BfMethodMatcher::FlushAmbiguityError()
|
void BfMethodMatcher::FlushAmbiguityError()
|
||||||
{
|
{
|
||||||
if (!mAmbiguousEntries.empty())
|
if (!mAmbiguousEntries.empty())
|
||||||
|
{
|
||||||
|
if (mModule->PreFail())
|
||||||
{
|
{
|
||||||
BfError* error;
|
BfError* error;
|
||||||
if (!mMethodName.empty())
|
if (!mMethodName.empty())
|
||||||
|
@ -2124,6 +2126,7 @@ void BfMethodMatcher::FlushAmbiguityError()
|
||||||
ambiguousEntry.mMethodInstance->mMethodDef->GetRefNode());
|
ambiguousEntry.mMethodInstance->mMethodDef->GetRefNode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mAmbiguousEntries.Clear();
|
mAmbiguousEntries.Clear();
|
||||||
}
|
}
|
||||||
|
@ -3759,6 +3762,12 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI
|
||||||
|
|
||||||
if (!thisValue.HasType())
|
if (!thisValue.HasType())
|
||||||
{
|
{
|
||||||
|
if ((mModule->mContext->mCurTypeState != NULL) && (mModule->mContext->mCurTypeState->mTypeInstance == mModule->mCurTypeInstance) &&
|
||||||
|
(mModule->mContext->mCurTypeState->mResolveKind == BfTypeState::ResolveKind_Attributes))
|
||||||
|
{
|
||||||
|
// Can't do static lookups yet
|
||||||
|
}
|
||||||
|
else
|
||||||
thisValue = BfTypedValue(mModule->mCurTypeInstance);
|
thisValue = BfTypedValue(mModule->mCurTypeInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4314,6 +4323,8 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
else if (!target)
|
else if (!target)
|
||||||
|
{
|
||||||
|
if (mModule->PreFail())
|
||||||
{
|
{
|
||||||
if ((flags & BfLookupFieldFlag_CheckingOuter) != 0)
|
if ((flags & BfLookupFieldFlag_CheckingOuter) != 0)
|
||||||
mModule->Fail(StrFormat("An instance reference is required to reference non-static outer field '%s.%s'", mModule->TypeToString(curCheckType).c_str(), field->mName.c_str()),
|
mModule->Fail(StrFormat("An instance reference is required to reference non-static outer field '%s.%s'", mModule->TypeToString(curCheckType).c_str(), field->mName.c_str()),
|
||||||
|
@ -4322,6 +4333,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
mModule->Fail(StrFormat("Cannot reference field '%s' before append allocations", field->mName.c_str()), targetSrc);
|
mModule->Fail(StrFormat("Cannot reference field '%s' before append allocations", field->mName.c_str()), targetSrc);
|
||||||
else
|
else
|
||||||
mModule->Fail(StrFormat("Cannot reference non-static field '%s' from a static method", field->mName.c_str()), targetSrc);
|
mModule->Fail(StrFormat("Cannot reference non-static field '%s' from a static method", field->mName.c_str()), targetSrc);
|
||||||
|
}
|
||||||
return mModule->GetDefaultTypedValue(resolvedFieldType, false, BfDefaultValueKind_Addr);
|
return mModule->GetDefaultTypedValue(resolvedFieldType, false, BfDefaultValueKind_Addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4500,6 +4512,8 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (matchedProp != NULL)
|
if (matchedProp != NULL)
|
||||||
|
{
|
||||||
|
if (mModule->PreFail())
|
||||||
{
|
{
|
||||||
auto error = mModule->Fail(StrFormat("Ambiguous reference to property '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
|
auto error = mModule->Fail(StrFormat("Ambiguous reference to property '%s.%s'", mModule->TypeToString(curCheckType).c_str(), fieldName.c_str()), targetSrc);
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
|
@ -4509,6 +4523,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
matchedProp = prop;
|
matchedProp = prop;
|
||||||
}
|
}
|
||||||
|
@ -6201,6 +6216,8 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argExprIdx < (int)argValues.size())
|
if (argExprIdx < (int)argValues.size())
|
||||||
|
{
|
||||||
|
if (mModule->PreFail())
|
||||||
{
|
{
|
||||||
BfAstNode* errorRef = argValues[argExprIdx].mExpression;
|
BfAstNode* errorRef = argValues[argExprIdx].mExpression;
|
||||||
if (errorRef == NULL)
|
if (errorRef == NULL)
|
||||||
|
@ -6227,6 +6244,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", (int)argValues.size() - argExprIdx), errorRef);
|
error = mModule->Fail(StrFormat("Too many arguments, expected %d fewer.", (int)argValues.size() - argExprIdx), errorRef);
|
||||||
if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
|
if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||||
|
}
|
||||||
failed = true;
|
failed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -6487,9 +6505,12 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
|
|
||||||
|
|
||||||
if (showCtorError)
|
if (showCtorError)
|
||||||
|
{
|
||||||
|
if (mModule->PreFail())
|
||||||
{
|
{
|
||||||
error = mModule->Fail(StrFormat("No parameterless constructor is available for base class. Consider calling base constructor '%s'.",
|
error = mModule->Fail(StrFormat("No parameterless constructor is available for base class. Consider calling base constructor '%s'.",
|
||||||
mModule->MethodToString(methodInstance).c_str()), refNode);
|
mModule->MethodToString(methodInstance).c_str()), refNode);
|
||||||
|
}
|
||||||
|
|
||||||
auto srcNode = mModule->mCurMethodInstance->mMethodDef->GetRefNode();
|
auto srcNode = mModule->mCurMethodInstance->mMethodDef->GetRefNode();
|
||||||
if ((autoComplete != NULL) && (autoComplete->CheckFixit(srcNode)))
|
if ((autoComplete != NULL) && (autoComplete->CheckFixit(srcNode)))
|
||||||
|
@ -6497,10 +6518,13 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mModule->PreFail())
|
||||||
|
{
|
||||||
if (error == NULL)
|
if (error == NULL)
|
||||||
error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", methodInstance->GetParamCount() - paramIdx), refNode);
|
error = mModule->Fail(StrFormat("Not enough parameters specified, expected %d more.", methodInstance->GetParamCount() - paramIdx), refNode);
|
||||||
if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
|
if ((error != NULL) && (methodInstance->mMethodDef->mMethodDeclaration != NULL))
|
||||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodInstance->mMethodDef->GetRefNode());
|
||||||
|
}
|
||||||
failed = true;
|
failed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -758,6 +758,20 @@ BfIRValue BfIRConstHolder::CreateConstAgg(BfIRType type, const BfSizedArray<BfIR
|
||||||
return irValue;
|
return irValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfIRValue BfIRConstHolder::CreateConstAggCE(BfIRType type, addr_ce addr)
|
||||||
|
{
|
||||||
|
BfConstantAggCE* constant = mTempAlloc.Alloc<BfConstantAggCE>();
|
||||||
|
constant->mConstType = BfConstType_AggCE;
|
||||||
|
constant->mType = type = type;
|
||||||
|
constant->mCEAddr = addr;
|
||||||
|
auto irValue = BfIRValue(BfIRValueFlags_Const, mTempAlloc.GetChunkedId(constant));
|
||||||
|
|
||||||
|
#ifdef CHECK_CONSTHOLDER
|
||||||
|
irValue.mHolder = this;
|
||||||
|
#endif
|
||||||
|
return irValue;
|
||||||
|
}
|
||||||
|
|
||||||
BfIRValue BfIRConstHolder::CreateConstArrayZero(BfIRType type, int count)
|
BfIRValue BfIRConstHolder::CreateConstArrayZero(BfIRType type, int count)
|
||||||
{
|
{
|
||||||
BfConstantArrayZero* constant = mTempAlloc.Alloc<BfConstantArrayZero>();
|
BfConstantArrayZero* constant = mTempAlloc.Alloc<BfConstantArrayZero>();
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
NS_BF_BEGIN
|
NS_BF_BEGIN
|
||||||
|
|
||||||
|
typedef int addr_ce;
|
||||||
|
|
||||||
class BfModule;
|
class BfModule;
|
||||||
class BfType;
|
class BfType;
|
||||||
class BfTypeInstance;
|
class BfTypeInstance;
|
||||||
|
@ -123,6 +125,7 @@ enum BfConstType
|
||||||
BfConstType_TypeOf_WithData,
|
BfConstType_TypeOf_WithData,
|
||||||
BfConstType_AggZero,
|
BfConstType_AggZero,
|
||||||
BfConstType_Agg,
|
BfConstType_Agg,
|
||||||
|
BfConstType_AggCE,
|
||||||
BfConstType_ArrayZero,
|
BfConstType_ArrayZero,
|
||||||
BfConstType_ArrayZero8,
|
BfConstType_ArrayZero8,
|
||||||
BfConstType_Undef,
|
BfConstType_Undef,
|
||||||
|
@ -874,6 +877,13 @@ struct BfConstantAgg
|
||||||
BfSizedArray<BfIRValue> mValues;
|
BfSizedArray<BfIRValue> mValues;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BfConstantAggCE
|
||||||
|
{
|
||||||
|
BfConstType mConstType;
|
||||||
|
BfIRType mType;
|
||||||
|
addr_ce mCEAddr;
|
||||||
|
};
|
||||||
|
|
||||||
struct BfConstantArrayZero
|
struct BfConstantArrayZero
|
||||||
{
|
{
|
||||||
BfConstType mConstType;
|
BfConstType mConstType;
|
||||||
|
@ -904,6 +914,7 @@ public:
|
||||||
bool TryGetBool(BfIRValue id, bool& boolVal);
|
bool TryGetBool(BfIRValue id, bool& boolVal);
|
||||||
int IsZero(BfIRValue val);
|
int IsZero(BfIRValue val);
|
||||||
int CheckConstEquality(BfIRValue lhs, BfIRValue rhs); // -1 = fail, 0 = false, 1 = true
|
int CheckConstEquality(BfIRValue lhs, BfIRValue rhs); // -1 = fail, 0 = false, 1 = true
|
||||||
|
//void WriteConstant(void* data, BeConstant* constVal);
|
||||||
|
|
||||||
BfIRValue CreateConst(BfTypeCode typeCode, uint64 val);
|
BfIRValue CreateConst(BfTypeCode typeCode, uint64 val);
|
||||||
BfIRValue CreateConst(BfTypeCode typeCode, int val);
|
BfIRValue CreateConst(BfTypeCode typeCode, int val);
|
||||||
|
@ -913,6 +924,7 @@ public:
|
||||||
BfIRValue CreateConstNull(BfIRType nullType);
|
BfIRValue CreateConstNull(BfIRType nullType);
|
||||||
BfIRValue CreateConstStructZero(BfIRType aggType);
|
BfIRValue CreateConstStructZero(BfIRType aggType);
|
||||||
BfIRValue CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values);
|
BfIRValue CreateConstAgg(BfIRType type, const BfSizedArray<BfIRValue>& values);
|
||||||
|
BfIRValue CreateConstAggCE(BfIRType type, addr_ce ptr);
|
||||||
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
BfIRValue CreateConstArrayZero(BfIRType type, int count);
|
||||||
BfIRValue CreateConstArrayZero(int count);
|
BfIRValue CreateConstArrayZero(int count);
|
||||||
BfIRValue CreateTypeOf(BfType* type);
|
BfIRValue CreateTypeOf(BfType* type);
|
||||||
|
|
|
@ -2714,6 +2714,14 @@ void BfModule::SetElementType(BfAstNode* astNode, BfSourceElementType elementTyp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BfModule::PreFail()
|
||||||
|
{
|
||||||
|
if (!mIgnoreErrors)
|
||||||
|
return true;
|
||||||
|
SetFail();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BfModule::SetFail()
|
void BfModule::SetFail()
|
||||||
{
|
{
|
||||||
if (mIgnoreErrors)
|
if (mIgnoreErrors)
|
||||||
|
@ -2758,7 +2766,7 @@ bool BfModule::IsSkippingExtraResolveChecks()
|
||||||
return mCompiler->IsSkippingExtraResolveChecks();
|
return mCompiler->IsSkippingExtraResolveChecks();
|
||||||
}
|
}
|
||||||
|
|
||||||
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent)
|
BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPersistent, bool deferError)
|
||||||
{
|
{
|
||||||
BP_ZONE("BfModule::Fail");
|
BP_ZONE("BfModule::Fail");
|
||||||
|
|
||||||
|
@ -2825,7 +2833,7 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
{
|
{
|
||||||
auto _CheckMethodInstance = [&](BfMethodInstance* methodInstance)
|
auto _CheckMethodInstance = [&](BfMethodInstance* methodInstance)
|
||||||
{
|
{
|
||||||
// Propogatea the fail all the way to the main method (assuming we're in a local method or lambda)
|
// Propogate the fail all the way to the main method (assuming we're in a local method or lambda)
|
||||||
methodInstance->mHasFailed = true;
|
methodInstance->mHasFailed = true;
|
||||||
|
|
||||||
bool isSpecializedMethod = ((methodInstance != NULL) && (!methodInstance->mIsUnspecialized) && (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mMethodGenericArguments.size() != 0));
|
bool isSpecializedMethod = ((methodInstance != NULL) && (!methodInstance->mIsUnspecialized) && (methodInstance->mMethodInfoEx != NULL) && (methodInstance->mMethodInfoEx->mMethodGenericArguments.size() != 0));
|
||||||
|
@ -2887,19 +2895,19 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
||||||
if (!_CheckMethodInstance(mCurMethodInstance))
|
if (!_CheckMethodInstance(mCurMethodInstance))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Keep in mind that all method specializations with generic type instances as its method generic params
|
// Keep in mind that all method specializations with generic type instances as its method generic params
|
||||||
// need to be deferred because the specified generic type instance might get deleted at the end of the
|
// need to be deferred because the specified generic type instance might get deleted at the end of the
|
||||||
// compilation due to no longer having indirect references removed, and we have to ignore errors from
|
// compilation due to no longer having indirect references removed, and we have to ignore errors from
|
||||||
// those method specializations if that occurs
|
// those method specializations if that occurs
|
||||||
if (isWhileSpecializing)
|
if ((isWhileSpecializing) || (deferError))
|
||||||
{
|
{
|
||||||
BfError* bfError = mCompiler->mPassInstance->DeferFail(errorString, refNode);
|
BfError* bfError = mCompiler->mPassInstance->DeferFail(errorString, refNode);
|
||||||
if (bfError != NULL)
|
if (bfError != NULL)
|
||||||
bfError->mIsWhileSpecializing = isWhileSpecializing;
|
bfError->mIsWhileSpecializing = isWhileSpecializing;
|
||||||
return bfError;
|
return bfError;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((!isWhileSpecializing) && (mCurTypeInstance != NULL) && ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType())))
|
if ((!isWhileSpecializing) && (mCurTypeInstance != NULL) && ((mCurTypeInstance->IsGenericTypeInstance()) && (!mCurTypeInstance->IsUnspecializedType())))
|
||||||
{
|
{
|
||||||
|
@ -10618,7 +10626,7 @@ BfTypedValue BfModule::GetTypedValueFromConstant(BfConstant* constant, BfIRConst
|
||||||
return BfTypedValue(irValue, wantType, false);
|
return BfTypedValue(irValue, wantType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType)
|
BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowStringId)
|
||||||
{
|
{
|
||||||
if (constant->mTypeCode == BfTypeCode_NullPtr)
|
if (constant->mTypeCode == BfTypeCode_NullPtr)
|
||||||
{
|
{
|
||||||
|
@ -10632,6 +10640,8 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
||||||
}
|
}
|
||||||
|
|
||||||
if (constant->mTypeCode == BfTypeCode_StringId)
|
if (constant->mTypeCode == BfTypeCode_StringId)
|
||||||
|
{
|
||||||
|
if (!allowStringId)
|
||||||
{
|
{
|
||||||
if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
|
if ((wantType->IsInstanceOf(mCompiler->mStringTypeDef)) ||
|
||||||
((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
|
((wantType->IsPointer()) && (wantType->GetUnderlyingType() == GetPrimitiveType(BfTypeCode_Char8))))
|
||||||
|
@ -10643,6 +10653,7 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
||||||
return stringObjConst;
|
return stringObjConst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (constant->mConstType == BfConstType_Agg)
|
if (constant->mConstType == BfConstType_Agg)
|
||||||
{
|
{
|
||||||
|
@ -10686,7 +10697,7 @@ BfIRValue BfModule::ConstantToCurrent(BfConstant* constant, BfIRConstHolder* con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(wantType), newVals);
|
return mBfIRBuilder->CreateConstAgg(mBfIRBuilder->MapType(wantType, BfIRPopulateType_Identity), newVals);
|
||||||
}
|
}
|
||||||
|
|
||||||
return mBfIRBuilder->CreateConst(constant, constHolder);
|
return mBfIRBuilder->CreateConst(constant, constHolder);
|
||||||
|
@ -10838,6 +10849,23 @@ void BfModule::GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttri
|
||||||
|
|
||||||
customAttribute.mType = attrTypeInst;
|
customAttribute.mType = attrTypeInst;
|
||||||
|
|
||||||
|
bool allocatedMethodState = NULL;
|
||||||
|
defer(
|
||||||
|
{
|
||||||
|
if (allocatedMethodState)
|
||||||
|
{
|
||||||
|
delete mCurMethodState;
|
||||||
|
mCurMethodState = NULL;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (mCurMethodState == NULL)
|
||||||
|
{
|
||||||
|
allocatedMethodState = true;
|
||||||
|
mCurMethodState = new BfMethodState();
|
||||||
|
mCurMethodState->mTempKind = BfMethodState::TempKind_Static;
|
||||||
|
}
|
||||||
|
|
||||||
BfConstResolver constResolver(this);
|
BfConstResolver constResolver(this);
|
||||||
if (allowNonConstArgs)
|
if (allowNonConstArgs)
|
||||||
constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowNonConst);
|
constResolver.mBfEvalExprFlags = (BfEvalExprFlags)(constResolver.mBfEvalExprFlags | BfEvalExprFlags_AllowNonConst);
|
||||||
|
@ -19747,6 +19775,10 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
|
||||||
mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
|
mBfIRBuilder->Func_DeleteBody(mCurMethodInstance->mIRFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid linking any internal funcs that were just supposed to be comptime-accessible
|
||||||
|
if (((methodInstance->mComptimeFlags & BfComptimeFlag_OnlyFromComptime) != 0) && (!mIsComptimeModule))
|
||||||
|
wantsRemoveBody = true;
|
||||||
|
|
||||||
if ((hasExternSpecifier) && (!skipBody))
|
if ((hasExternSpecifier) && (!skipBody))
|
||||||
{
|
{
|
||||||
// If we hot swap, we want to make sure at least one method refers to this extern method so it gets pulled in
|
// If we hot swap, we want to make sure at least one method refers to this extern method so it gets pulled in
|
||||||
|
|
|
@ -1481,10 +1481,11 @@ public:
|
||||||
void GetAccessAllowed(BfTypeInstance* checkType, bool& allowProtected, bool& allowPrivate);
|
void GetAccessAllowed(BfTypeInstance* checkType, bool& allowProtected, bool& allowPrivate);
|
||||||
bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType);
|
bool CheckProtection(BfProtectionCheckFlags& flags, BfTypeInstance* memberOwner, BfProject* memberProject, BfProtection memberProtection, BfTypeInstance* lookupStartType);
|
||||||
void SetElementType(BfAstNode* astNode, BfSourceElementType elementType);
|
void SetElementType(BfAstNode* astNode, BfSourceElementType elementType);
|
||||||
|
bool PreFail();
|
||||||
void SetFail();
|
void SetFail();
|
||||||
void VerifyOnDemandMethods();
|
void VerifyOnDemandMethods();
|
||||||
bool IsSkippingExtraResolveChecks();
|
bool IsSkippingExtraResolveChecks();
|
||||||
BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false);
|
BfError* Fail(const StringImpl& error, BfAstNode* refNode = NULL, bool isPersistent = false, bool deferError = false);
|
||||||
BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);
|
BfError* FailInternal(const StringImpl& error, BfAstNode* refNode = NULL);
|
||||||
BfError* FailAfter(const StringImpl& error, BfAstNode* refNode);
|
BfError* FailAfter(const StringImpl& error, BfAstNode* refNode);
|
||||||
BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false);
|
BfError* Warn(int warningNum, const StringImpl& warning, BfAstNode* refNode = NULL, bool isPersistent = false);
|
||||||
|
@ -1526,7 +1527,7 @@ public:
|
||||||
void CurrentAddToConstHolder(BfIRValue& irVal);
|
void CurrentAddToConstHolder(BfIRValue& irVal);
|
||||||
void ClearConstData();
|
void ClearConstData();
|
||||||
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
BfTypedValue GetTypedValueFromConstant(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
||||||
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType);
|
BfIRValue ConstantToCurrent(BfConstant* constant, BfIRConstHolder* constHolder, BfType* wantType, bool allowStringId = false);
|
||||||
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
void ValidateCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeTargets attrTarget);
|
||||||
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
void GetCustomAttributes(BfCustomAttributes* customAttributes, BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||||
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
BfCustomAttributes* GetCustomAttributes(BfAttributeDirective* attributesDirective, BfAttributeTargets attrType, bool allowNonConstArgs = false, BfCaptureInfo* captureInfo = NULL);
|
||||||
|
@ -1698,7 +1699,8 @@ public:
|
||||||
BfModuleOptions GetModuleOptions();
|
BfModuleOptions GetModuleOptions();
|
||||||
BfCheckedKind GetDefaultCheckedKind();
|
BfCheckedKind GetDefaultCheckedKind();
|
||||||
void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& ctxString, BfAstNode* refNode);
|
void UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfTypeDef* activeTypeDef, const StringImpl& ctxString, BfAstNode* refNode);
|
||||||
void ExecuteCEOnCompile(BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind, CeEmitContext* ceEmitContext);
|
void HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes);
|
||||||
|
void ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInst, BfCEOnCompileKind onCompileKind);
|
||||||
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers);
|
void DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers);
|
||||||
void DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
void DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateType = BfPopulateType_Data);
|
||||||
static BfModule* GetModuleFor(BfType* type);
|
static BfModule* GetModuleFor(BfType* type);
|
||||||
|
|
|
@ -1952,9 +1952,11 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
|
||||||
src += ceEmitContext->mEmitData;
|
src += ceEmitContext->mEmitData;
|
||||||
ceEmitContext->mEmitData.Clear();
|
ceEmitContext->mEmitData.Clear();
|
||||||
|
|
||||||
|
bool createdParser = false;
|
||||||
int startSrcIdx = 0;
|
int startSrcIdx = 0;
|
||||||
if (activeTypeDef->mEmitParser == NULL)
|
if (activeTypeDef->mEmitParser == NULL)
|
||||||
{
|
{
|
||||||
|
createdParser = true;
|
||||||
BfParser* parser = new BfParser(mSystem, typeInstance->mTypeDef->mProject);
|
BfParser* parser = new BfParser(mSystem, typeInstance->mTypeDef->mProject);
|
||||||
parser->mIsEmitted = true;
|
parser->mIsEmitted = true;
|
||||||
parser->mFileName = typeInstance->mTypeDef->mName->ToString();
|
parser->mFileName = typeInstance->mTypeDef->mName->ToString();
|
||||||
|
@ -1999,11 +2001,14 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
|
||||||
bfReducer.HandleTypeDeclaration(typeDeclaration, NULL);
|
bfReducer.HandleTypeDeclaration(typeDeclaration, NULL);
|
||||||
|
|
||||||
BfDefBuilder defBuilder(mSystem);
|
BfDefBuilder defBuilder(mSystem);
|
||||||
|
defBuilder.mCurSource = activeTypeDef->mEmitParser;
|
||||||
defBuilder.mCurTypeDef = typeInstance->mTypeDef;
|
defBuilder.mCurTypeDef = typeInstance->mTypeDef;
|
||||||
|
defBuilder.mPassInstance = mCompiler->mPassInstance;
|
||||||
|
defBuilder.mIsComptime = true;
|
||||||
defBuilder.DoVisitChild(typeDeclaration->mDefineNode);
|
defBuilder.DoVisitChild(typeDeclaration->mDefineNode);
|
||||||
defBuilder.FinishTypeDef(typeInstance->mTypeDef->mTypeCode == BfTypeCode_Enum);
|
defBuilder.FinishTypeDef(typeInstance->mTypeDef->mTypeCode == BfTypeCode_Enum);
|
||||||
|
|
||||||
//
|
if (createdParser)
|
||||||
{
|
{
|
||||||
AutoCrit crit(mSystem->mDataLock);
|
AutoCrit crit(mSystem->mDataLock);
|
||||||
mSystem->mParsers.Add(activeTypeDef->mEmitParser);
|
mSystem->mParsers.Add(activeTypeDef->mEmitParser);
|
||||||
|
@ -2020,10 +2025,77 @@ void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::ExecuteCEOnCompile(BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind, CeEmitContext* ceEmitContext)
|
void BfModule::HandleCEAttributes(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCustomAttributes* customAttributes, HashSet<BfTypeInstance*> foundAttributes)
|
||||||
{
|
{
|
||||||
if (!typeInstance->mTypeDef->mHasCEOnCompile)
|
BfTypeInstance* iComptimeTypeApply = NULL;
|
||||||
return;
|
for (auto& customAttribute : customAttributes->mAttributes)
|
||||||
|
{
|
||||||
|
auto attrType = customAttribute.mType;
|
||||||
|
PopulateType(attrType, BfPopulateType_DataAndMethods);
|
||||||
|
if (attrType->mDefineState < BfTypeDefineState_DefinedAndMethodsSlotted)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (auto& ifaceEntry : attrType->mInterfaces)
|
||||||
|
{
|
||||||
|
if (iComptimeTypeApply == NULL)
|
||||||
|
iComptimeTypeApply = ResolveTypeDef(mCompiler->mIComptimeTypeApply)->ToTypeInstance();
|
||||||
|
if (ifaceEntry.mInterfaceType != iComptimeTypeApply)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!foundAttributes.Add(attrType))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
BfMethodInstance* methodInstance = attrType->mInterfaceMethodTable[ifaceEntry.mStartInterfaceTableIdx].mMethodRef;
|
||||||
|
if (methodInstance == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext, ceEmitContext);
|
||||||
|
auto ceContext = mCompiler->mCEMachine->AllocContext();
|
||||||
|
|
||||||
|
BfIRValue attrVal = ceContext->CreateAttribute(customAttribute.mRef, this, typeInstance->mConstHolder, &customAttribute);
|
||||||
|
|
||||||
|
SizedArray<BfIRValue, 1> args;
|
||||||
|
if (!attrType->IsValuelessType())
|
||||||
|
args.Add(attrVal);
|
||||||
|
args.Add(mBfIRBuilder->CreateTypeOf(typeInstance));
|
||||||
|
|
||||||
|
//TESTING
|
||||||
|
// mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||||
|
// ceContext = mCompiler->mCEMachine->AllocContext();
|
||||||
|
// ceContext->mMemory.mSize = ceContext->mMemory.mAllocSize;
|
||||||
|
|
||||||
|
auto result = ceContext->Call(customAttribute.mRef, this, methodInstance, args, CeEvalFlags_None, NULL);
|
||||||
|
|
||||||
|
if (!ceEmitContext->mEmitData.IsEmpty())
|
||||||
|
{
|
||||||
|
String ctxStr = "comptime ApplyToType of ";
|
||||||
|
ctxStr += TypeToString(attrType);
|
||||||
|
ctxStr += " to ";
|
||||||
|
ctxStr += TypeToString(typeInstance);
|
||||||
|
ctxStr += " ";
|
||||||
|
ctxStr += customAttribute.mRef->LocationToString();
|
||||||
|
UpdateCEEmit(ceEmitContext, typeInstance, typeInstance->mTypeDef, ctxStr, customAttribute.mRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
mCompiler->mCEMachine->ReleaseContext(ceContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BfModule::ExecuteCEOnCompile(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, BfCEOnCompileKind onCompileKind)
|
||||||
|
{
|
||||||
|
HashSet<BfTypeInstance*> foundAttributes;
|
||||||
|
if (ceEmitContext != NULL)
|
||||||
|
{
|
||||||
|
if (typeInstance->mCustomAttributes != NULL)
|
||||||
|
HandleCEAttributes(ceEmitContext, typeInstance, typeInstance->mCustomAttributes, foundAttributes);
|
||||||
|
|
||||||
|
for (auto& fieldInstance : typeInstance->mFieldInstances)
|
||||||
|
{
|
||||||
|
if (fieldInstance.mCustomAttributes != NULL)
|
||||||
|
HandleCEAttributes(ceEmitContext, typeInstance, fieldInstance.mCustomAttributes, foundAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int methodCount = (int)typeInstance->mTypeDef->mMethods.size();
|
int methodCount = (int)typeInstance->mTypeDef->mMethods.size();
|
||||||
for (int methodIdx = 0; methodIdx < methodCount; methodIdx++)
|
for (int methodIdx = 0; methodIdx < methodCount; methodIdx++)
|
||||||
|
@ -2034,6 +2106,28 @@ void BfModule::ExecuteCEOnCompile(BfTypeInstance* typeInstance, BfCEOnCompileKin
|
||||||
continue;
|
continue;
|
||||||
if (methodDeclaration->mAttributes == NULL)
|
if (methodDeclaration->mAttributes == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
bool wantsAttributes = false;
|
||||||
|
BfAttributeDirective* checkAttributes = methodDeclaration->mAttributes;
|
||||||
|
while (checkAttributes != NULL)
|
||||||
|
{
|
||||||
|
SetAndRestoreValue<bool> prevIgnoreErrors(mIgnoreErrors, true);
|
||||||
|
BfType* attrType = ResolveTypeRef(checkAttributes->mAttributeTypeRef, BfPopulateType_Identity, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_Attribute | BfResolveTypeRefFlag_NoReify));
|
||||||
|
if (attrType != NULL)
|
||||||
|
{
|
||||||
|
if (attrType->IsInstanceOf(mCompiler->mOnCompileAttributeTypeDef))
|
||||||
|
wantsAttributes = true;
|
||||||
|
auto attrTypeInstance = attrType->ToTypeInstance();
|
||||||
|
if ((attrTypeInstance != NULL) && (!attrTypeInstance->mInterfaces.IsEmpty()))
|
||||||
|
wantsAttributes = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
checkAttributes = checkAttributes->mNextAttribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wantsAttributes)
|
||||||
|
return;
|
||||||
|
|
||||||
auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method);
|
auto customAttributes = GetCustomAttributes(methodDeclaration->mAttributes, BfAttributeTargets_Method);
|
||||||
defer({ delete customAttributes; });
|
defer({ delete customAttributes; });
|
||||||
|
|
||||||
|
@ -2041,6 +2135,8 @@ void BfModule::ExecuteCEOnCompile(BfTypeInstance* typeInstance, BfCEOnCompileKin
|
||||||
if (onCompileAttribute == NULL)
|
if (onCompileAttribute == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
HandleCEAttributes(ceEmitContext, typeInstance, customAttributes, foundAttributes);
|
||||||
|
|
||||||
if (onCompileAttribute->mCtorArgs.size() < 1)
|
if (onCompileAttribute->mCtorArgs.size() < 1)
|
||||||
continue;
|
continue;
|
||||||
auto constant = typeInstance->mConstHolder->GetConstant(onCompileAttribute->mCtorArgs[0]);
|
auto constant = typeInstance->mConstHolder->GetConstant(onCompileAttribute->mCtorArgs[0]);
|
||||||
|
@ -2062,7 +2158,6 @@ void BfModule::ExecuteCEOnCompile(BfTypeInstance* typeInstance, BfCEOnCompileKin
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext);
|
SetAndRestoreValue<CeEmitContext*> prevEmitContext(mCompiler->mCEMachine->mCurEmitContext);
|
||||||
|
|
||||||
if (onCompileKind == BfCEOnCompileKind_TypeInit)
|
if (onCompileKind == BfCEOnCompileKind_TypeInit)
|
||||||
{
|
{
|
||||||
mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
|
mCompiler->mCEMachine->mCurEmitContext = ceEmitContext;
|
||||||
|
@ -2075,6 +2170,8 @@ void BfModule::ExecuteCEOnCompile(BfTypeInstance* typeInstance, BfCEOnCompileKin
|
||||||
{
|
{
|
||||||
String ctxStr = "OnCompile execution of ";
|
String ctxStr = "OnCompile execution of ";
|
||||||
ctxStr += MethodToString(methodInstance);
|
ctxStr += MethodToString(methodInstance);
|
||||||
|
ctxStr += " ";
|
||||||
|
ctxStr += methodInstance->mMethodDef->GetRefNode()->LocationToString();
|
||||||
UpdateCEEmit(ceEmitContext, typeInstance, methodInstance->mMethodDef->mDeclaringType, ctxStr, methodInstance->mMethodDef->GetRefNode());
|
UpdateCEEmit(ceEmitContext, typeInstance, methodInstance->mMethodDef->mDeclaringType, ctxStr, methodInstance->mMethodDef->GetRefNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2091,13 +2188,15 @@ void BfModule::DoCEEmit(BfTypeInstance* typeInstance, bool& hadNewMembers)
|
||||||
|
|
||||||
int startMethodCount = typeInstance->mTypeDef->mMethods.mSize;
|
int startMethodCount = typeInstance->mTypeDef->mMethods.mSize;
|
||||||
int startFieldCount = typeInstance->mTypeDef->mFields.mSize;
|
int startFieldCount = typeInstance->mTypeDef->mFields.mSize;
|
||||||
|
int startPropCount = typeInstance->mTypeDef->mProperties.mSize;
|
||||||
|
|
||||||
CeEmitContext emitContext;
|
CeEmitContext emitContext;
|
||||||
emitContext.mType = typeInstance;
|
emitContext.mType = typeInstance;
|
||||||
ExecuteCEOnCompile(typeInstance, BfCEOnCompileKind_TypeInit, &emitContext);
|
ExecuteCEOnCompile(&emitContext, typeInstance, BfCEOnCompileKind_TypeInit);
|
||||||
|
|
||||||
if ((startMethodCount != typeInstance->mTypeDef->mMethods.mSize) ||
|
if ((startMethodCount != typeInstance->mTypeDef->mMethods.mSize) ||
|
||||||
(startFieldCount != typeInstance->mTypeDef->mFields.mSize))
|
(startFieldCount != typeInstance->mTypeDef->mFields.mSize) ||
|
||||||
|
(startPropCount != typeInstance->mTypeDef->mProperties.mSize))
|
||||||
{
|
{
|
||||||
typeInstance->mTypeDef->ClearMemberSets();
|
typeInstance->mTypeDef->ClearMemberSets();
|
||||||
hadNewMembers = true;
|
hadNewMembers = true;
|
||||||
|
@ -3004,6 +3103,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
attrTarget = BfAttributeTargets_Class;
|
attrTarget = BfAttributeTargets_Class;
|
||||||
if (!typeInstance->mTypeFailed)
|
if (!typeInstance->mTypeFailed)
|
||||||
{
|
{
|
||||||
|
BfTypeState typeState;
|
||||||
|
typeState.mPrevState = mContext->mCurTypeState;
|
||||||
|
typeState.mResolveKind = BfTypeState::ResolveKind_Attributes;
|
||||||
|
typeState.mTypeInstance = typeInstance;
|
||||||
|
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
||||||
|
|
||||||
// This allows us to avoid reentrancy when checking for inner types
|
// This allows us to avoid reentrancy when checking for inner types
|
||||||
SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
|
SetAndRestoreValue<bool> prevSkipTypeProtectionChecks(typeInstance->mSkipTypeProtectionChecks, true);
|
||||||
if (typeDef->mIsCombinedPartial)
|
if (typeDef->mIsCombinedPartial)
|
||||||
|
@ -3012,22 +3117,20 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
{
|
{
|
||||||
if (partialTypeDef->mTypeDeclaration->mAttributes == NULL)
|
if (partialTypeDef->mTypeDeclaration->mAttributes == NULL)
|
||||||
continue;
|
continue;
|
||||||
BfTypeState typeState;
|
|
||||||
typeState.mPrevState = mContext->mCurTypeState;
|
|
||||||
typeState.mCurTypeDef = partialTypeDef;
|
|
||||||
typeState.mTypeInstance = typeInstance;
|
|
||||||
SetAndRestoreValue<BfTypeState*> prevTypeState(mContext->mCurTypeState, &typeState);
|
|
||||||
|
|
||||||
|
typeState.mCurTypeDef = partialTypeDef;
|
||||||
if (typeInstance->mCustomAttributes == NULL)
|
if (typeInstance->mCustomAttributes == NULL)
|
||||||
typeInstance->mCustomAttributes = new BfCustomAttributes();
|
typeInstance->mCustomAttributes = new BfCustomAttributes();
|
||||||
GetCustomAttributes(typeInstance->mCustomAttributes, partialTypeDef->mTypeDeclaration->mAttributes, attrTarget);
|
GetCustomAttributes(typeInstance->mCustomAttributes, partialTypeDef->mTypeDeclaration->mAttributes, attrTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
typeInstance->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, attrTarget);
|
typeInstance->mCustomAttributes = GetCustomAttributes(typeDef->mTypeDeclaration->mAttributes, attrTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (typeInstance->mTypeOptionsIdx == -2)
|
if (typeInstance->mTypeOptionsIdx == -2)
|
||||||
SetTypeOptions(typeInstance);
|
SetTypeOptions(typeInstance);
|
||||||
|
@ -3364,10 +3467,10 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
|
|
||||||
auto refNode = typeDef->GetRefNode();
|
auto refNode = typeDef->GetRefNode();
|
||||||
Fail(error, refNode);
|
Fail(error, refNode);
|
||||||
if (mCompiler->mCEMachine->mCurFrame != NULL)
|
if ((mCompiler->mCEMachine->mCurContext != NULL) && (mCompiler->mCEMachine->mCurContext->mCurFrame != NULL))
|
||||||
mCompiler->mCEMachine->Fail(*mCompiler->mCEMachine->mCurFrame, error);
|
mCompiler->mCEMachine->mCurContext->Fail(*mCompiler->mCEMachine->mCurContext->mCurFrame, error);
|
||||||
else
|
else if (mCompiler->mCEMachine->mCurContext != NULL)
|
||||||
mCompiler->mCEMachine->Fail(error);
|
mCompiler->mCEMachine->mCurContext->Fail(error);
|
||||||
}
|
}
|
||||||
else if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
else if (typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit)
|
||||||
{
|
{
|
||||||
|
@ -3906,7 +4009,7 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
{
|
{
|
||||||
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
typeInstance->mDefineState = BfTypeDefineState_Defined;
|
||||||
if (!typeInstance->IsBoxed())
|
if (!typeInstance->IsBoxed())
|
||||||
ExecuteCEOnCompile(typeInstance, BfCEOnCompileKind_TypeDone, NULL);
|
ExecuteCEOnCompile(NULL, typeInstance, BfCEOnCompileKind_TypeDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeInstance->mTypeFailed)
|
if (typeInstance->mTypeFailed)
|
||||||
|
|
|
@ -493,6 +493,8 @@ void BfParser::NewLine()
|
||||||
mLineStart = mSrcIdx;
|
mLineStart = mSrcIdx;
|
||||||
mLineNum++;
|
mLineNum++;
|
||||||
|
|
||||||
|
if (mJumpTable == NULL)
|
||||||
|
return;
|
||||||
int idx = (mSrcIdx / PARSER_JUMPTABLE_DIVIDE);
|
int idx = (mSrcIdx / PARSER_JUMPTABLE_DIVIDE);
|
||||||
if (idx == 0)
|
if (idx == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -575,6 +577,7 @@ void BfParser::SetSource(const char* data, int length)
|
||||||
mOrigSrcLength = length;
|
mOrigSrcLength = length;
|
||||||
mSrcAllocSize = mSrcLength /*+ EXTRA_BUFFER_SIZE*/;
|
mSrcAllocSize = mSrcLength /*+ EXTRA_BUFFER_SIZE*/;
|
||||||
char* ownedSrc = new char[mSrcAllocSize + 1];
|
char* ownedSrc = new char[mSrcAllocSize + 1];
|
||||||
|
if (data != NULL)
|
||||||
memcpy(ownedSrc, data, length);
|
memcpy(ownedSrc, data, length);
|
||||||
ownedSrc[length] = 0;
|
ownedSrc[length] = 0;
|
||||||
mSrc = ownedSrc;
|
mSrc = ownedSrc;
|
||||||
|
@ -3482,9 +3485,12 @@ void BfParser::Parse(BfPassInstance* passInstance)
|
||||||
mPassInstance->Warn(0, "No matching #endif found", mPreprocessorNodeStack.back().first);
|
mPassInstance->Warn(0, "No matching #endif found", mPreprocessorNodeStack.back().first);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mJumpTable != NULL)
|
||||||
|
{
|
||||||
for (int i = (startIdx / PARSER_JUMPTABLE_DIVIDE) + 1; i < mJumpTableSize; i++)
|
for (int i = (startIdx / PARSER_JUMPTABLE_DIVIDE) + 1; i < mJumpTableSize; i++)
|
||||||
if (mJumpTable[i].mCharIdx == 0)
|
if (mJumpTable[i].mCharIdx == 0)
|
||||||
mJumpTable[i] = mJumpTable[i - 1];
|
mJumpTable[i] = mJumpTable[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
if (mPassInstance->HasFailed())
|
if (mPassInstance->HasFailed())
|
||||||
mParsingFailed = true;
|
mParsingFailed = true;
|
||||||
|
|
|
@ -2671,6 +2671,14 @@ BfCustomAttribute* BfCustomAttributes::Get(BfTypeDef * typeDef)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfCustomAttribute* BfCustomAttributes::Get(BfType* type)
|
||||||
|
{
|
||||||
|
for (auto& customAttr : mAttributes)
|
||||||
|
if (customAttr.mType == type)
|
||||||
|
return &customAttr;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
BfResolvedTypeSet::~BfResolvedTypeSet()
|
BfResolvedTypeSet::~BfResolvedTypeSet()
|
||||||
|
|
|
@ -2410,6 +2410,7 @@ public:
|
||||||
Array<BfCustomAttribute> mAttributes;
|
Array<BfCustomAttribute> mAttributes;
|
||||||
bool Contains(BfTypeDef* typeDef);
|
bool Contains(BfTypeDef* typeDef);
|
||||||
BfCustomAttribute* Get(BfTypeDef* typeDef);
|
BfCustomAttribute* Get(BfTypeDef* typeDef);
|
||||||
|
BfCustomAttribute* Get(BfType* type);
|
||||||
|
|
||||||
void ReportMemory(MemReporter* memReporter);
|
void ReportMemory(MemReporter* memReporter);
|
||||||
};
|
};
|
||||||
|
|
|
@ -696,7 +696,8 @@ void BfTypeDef::ClearEmitted()
|
||||||
for (int methodIdx = (int)mMethods.size() - 1; methodIdx >= 0; methodIdx--)
|
for (int methodIdx = (int)mMethods.size() - 1; methodIdx >= 0; methodIdx--)
|
||||||
{
|
{
|
||||||
auto methodDef = mMethods[methodIdx];
|
auto methodDef = mMethods[methodIdx];
|
||||||
if ((methodDef->mMethodDeclaration != NULL) && (methodDef->mMethodDeclaration->IsEmitted()))
|
if ((methodDef->mAddedAfterEmit) ||
|
||||||
|
((methodDef->mMethodDeclaration != NULL) && (methodDef->mMethodDeclaration->IsEmitted())))
|
||||||
{
|
{
|
||||||
delete methodDef;
|
delete methodDef;
|
||||||
mMethods.RemoveAt(methodIdx);
|
mMethods.RemoveAt(methodIdx);
|
||||||
|
@ -712,6 +713,16 @@ void BfTypeDef::ClearEmitted()
|
||||||
mFields.RemoveAt(fieldIdx);
|
mFields.RemoveAt(fieldIdx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int propIdx = (int)mProperties.size() - 1; propIdx >= 0; propIdx--)
|
||||||
|
{
|
||||||
|
auto propDef = mProperties[propIdx];
|
||||||
|
if ((propDef->mFieldDeclaration != NULL) && (propDef->mFieldDeclaration->IsEmitted()))
|
||||||
|
{
|
||||||
|
delete propDef;
|
||||||
|
mProperties.RemoveAt(propIdx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,6 +841,16 @@ BfMethodDef* BfTypeDef::GetMethodByName(const StringImpl& name, int paramCount)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BfFieldDef* BfTypeDef::GetFieldByName(const StringImpl& name)
|
||||||
|
{
|
||||||
|
PopulateMemberSets();
|
||||||
|
BfFieldDef* nextField = NULL;
|
||||||
|
BfMemberSetEntry* entry;
|
||||||
|
if (mFieldSet.TryGetWith(name, &entry))
|
||||||
|
return (BfFieldDef*)entry->mMemberDef;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
String BfTypeDef::ToString()
|
String BfTypeDef::ToString()
|
||||||
{
|
{
|
||||||
String typeName(mName->ToString());
|
String typeName(mName->ToString());
|
||||||
|
|
|
@ -41,6 +41,7 @@ class BfSystem;
|
||||||
class BfTypeReference;
|
class BfTypeReference;
|
||||||
class BfCompiler;
|
class BfCompiler;
|
||||||
class BfProject;
|
class BfProject;
|
||||||
|
class BfTypeDef;
|
||||||
|
|
||||||
struct BfTypeDefMapFuncs;
|
struct BfTypeDefMapFuncs;
|
||||||
typedef MultiHashSet<BfTypeDef*, BfTypeDefMapFuncs> BfTypeDefMap;
|
typedef MultiHashSet<BfTypeDef*, BfTypeDefMapFuncs> BfTypeDefMap;
|
||||||
|
@ -794,6 +795,7 @@ public:
|
||||||
bool mIsExtern;
|
bool mIsExtern;
|
||||||
bool mIsNoDiscard;
|
bool mIsNoDiscard;
|
||||||
bool mHasExplicitThis;
|
bool mHasExplicitThis;
|
||||||
|
bool mAddedAfterEmit;
|
||||||
BfCommutableKind mCommutableKind;
|
BfCommutableKind mCommutableKind;
|
||||||
BfCheckedKind mCheckedKind;
|
BfCheckedKind mCheckedKind;
|
||||||
BfImportKind mImportKind;
|
BfImportKind mImportKind;
|
||||||
|
@ -823,6 +825,7 @@ public:
|
||||||
mIsExtern = false;
|
mIsExtern = false;
|
||||||
mIsNoDiscard = false;
|
mIsNoDiscard = false;
|
||||||
mHasExplicitThis = false;
|
mHasExplicitThis = false;
|
||||||
|
mAddedAfterEmit = false;
|
||||||
mBody = NULL;
|
mBody = NULL;
|
||||||
mExplicitInterface = NULL;
|
mExplicitInterface = NULL;
|
||||||
mReturnTypeRef = NULL;
|
mReturnTypeRef = NULL;
|
||||||
|
@ -1054,6 +1057,7 @@ public:
|
||||||
int GetSelfGenericParamCount();
|
int GetSelfGenericParamCount();
|
||||||
String ToString();
|
String ToString();
|
||||||
BfMethodDef* GetMethodByName(const StringImpl& name, int paramCount = -1);
|
BfMethodDef* GetMethodByName(const StringImpl& name, int paramCount = -1);
|
||||||
|
BfFieldDef* GetFieldByName(const StringImpl& name);
|
||||||
bool HasAutoProperty(BfPropertyDeclaration* propertyDeclaration);
|
bool HasAutoProperty(BfPropertyDeclaration* propertyDeclaration);
|
||||||
String GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration);
|
String GetAutoPropertyName(BfPropertyDeclaration* propertyDeclaration);
|
||||||
BfAstNode* GetRefNode();
|
BfAstNode* GetRefNode();
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
NS_BF_BEGIN
|
NS_BF_BEGIN
|
||||||
|
|
||||||
|
class BfParser;
|
||||||
|
class BfReducer;
|
||||||
class BfMethodInstance;
|
class BfMethodInstance;
|
||||||
class BeModule;
|
class BeModule;
|
||||||
class BeContext;
|
class BeContext;
|
||||||
|
@ -23,8 +25,6 @@ class BeGlobalVariable;
|
||||||
class CeMachine;
|
class CeMachine;
|
||||||
class CeFunction;
|
class CeFunction;
|
||||||
|
|
||||||
typedef int addr_ce;
|
|
||||||
|
|
||||||
#define CEOP_SIZED(OPNAME) \
|
#define CEOP_SIZED(OPNAME) \
|
||||||
CeOp_##OPNAME##_8, \
|
CeOp_##OPNAME##_8, \
|
||||||
CeOp_##OPNAME##_16, \
|
CeOp_##OPNAME##_16, \
|
||||||
|
@ -251,6 +251,9 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_DebugWrite_Int,
|
CeFunctionKind_DebugWrite_Int,
|
||||||
CeFunctionKind_GetReflectType,
|
CeFunctionKind_GetReflectType,
|
||||||
CeFunctionKind_GetReflectTypeById,
|
CeFunctionKind_GetReflectTypeById,
|
||||||
|
CeFunctionKind_GetReflectTypeByName,
|
||||||
|
CeFunctionKind_GetReflectSpecializedType,
|
||||||
|
CeFunctionKind_Type_GetCustomAttribute,
|
||||||
CeFunctionKind_EmitDefinition,
|
CeFunctionKind_EmitDefinition,
|
||||||
CeFunctionKind_Sleep,
|
CeFunctionKind_Sleep,
|
||||||
CeFunctionKind_Char32_ToLower,
|
CeFunctionKind_Char32_ToLower,
|
||||||
|
@ -368,6 +371,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
~CeFunction();
|
~CeFunction();
|
||||||
|
void Print();
|
||||||
};
|
};
|
||||||
|
|
||||||
enum CeEvalFlags
|
enum CeEvalFlags
|
||||||
|
@ -424,8 +428,9 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
#define BF_CE_STACK_SIZE 4*1024*1024
|
#define BF_CE_STACK_SIZE 4*1024*1024
|
||||||
|
#define BF_CE_INITIAL_MEMORY BF_CE_STACK_SIZE + 128*1024
|
||||||
#define BF_CE_MAX_MEMORY 128*1024*1024
|
#define BF_CE_MAX_MEMORY 128*1024*1024
|
||||||
#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_STACK_SIZE + 1024*1024
|
#define BF_CE_MAX_CARRYOVER_MEMORY BF_CE_STACK_SIZE * 2
|
||||||
#define BF_CE_MAX_CARRYOVER_HEAP 1024*1024
|
#define BF_CE_MAX_CARRYOVER_HEAP 1024*1024
|
||||||
|
|
||||||
enum CeOperandInfoKind
|
enum CeOperandInfoKind
|
||||||
|
@ -518,6 +523,7 @@ public:
|
||||||
Dictionary<BeConstant*, int> mConstDataMap;
|
Dictionary<BeConstant*, int> mConstDataMap;
|
||||||
Dictionary<BeFunction*, int> mInnerFunctionMap;
|
Dictionary<BeFunction*, int> mInnerFunctionMap;
|
||||||
Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
|
Dictionary<BeGlobalVariable*, int> mStaticFieldMap;
|
||||||
|
Dictionary<String, BfFieldInstance*> mStaticFieldInstanceMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CeBuilder()
|
CeBuilder()
|
||||||
|
@ -586,13 +592,11 @@ public:
|
||||||
class CeStaticFieldInfo
|
class CeStaticFieldInfo
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
BfFieldInstance* mFieldInstance;
|
|
||||||
addr_ce mAddr;
|
addr_ce mAddr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CeStaticFieldInfo()
|
CeStaticFieldInfo()
|
||||||
{
|
{
|
||||||
mFieldInstance = NULL;
|
|
||||||
mAddr = 0;
|
mAddr = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -617,6 +621,62 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CeContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CeMachine* mCeMachine;
|
||||||
|
int mReflectTypeIdOffset;
|
||||||
|
int mExecuteId;
|
||||||
|
CeEvalFlags mCurEvalFlags;
|
||||||
|
|
||||||
|
// These are only valid for the current execution
|
||||||
|
ContiguousHeap* mHeap;
|
||||||
|
Array<CeFrame> mCallStack;
|
||||||
|
Array<uint8> mMemory;
|
||||||
|
Dictionary<int, addr_ce> mStringMap;
|
||||||
|
Dictionary<int, addr_ce> mReflectMap;
|
||||||
|
Dictionary<Val128, addr_ce> mConstDataMap;
|
||||||
|
HashSet<int> mStaticCtorExecSet;
|
||||||
|
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
|
||||||
|
Dictionary<void*, addr_ce> mMemToCtxMap;
|
||||||
|
|
||||||
|
BfMethodInstance* mCurMethodInstance;
|
||||||
|
BfType* mCurExpectingType;
|
||||||
|
BfAstNode* mCurTargetSrc;
|
||||||
|
BfModule* mCurModule;
|
||||||
|
CeFrame* mCurFrame;
|
||||||
|
CeEmitContext* mCurEmitContext;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CeContext();
|
||||||
|
~CeContext();
|
||||||
|
|
||||||
|
BfError* Fail(const StringImpl& error);
|
||||||
|
BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
|
||||||
|
|
||||||
|
uint8* CeMalloc(int size);
|
||||||
|
bool CeFree(addr_ce addr);
|
||||||
|
addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);
|
||||||
|
addr_ce GetReflectType(int typeId);
|
||||||
|
addr_ce GetReflectType(const String& typeName);
|
||||||
|
int GetTypeIdFromType(addr_ce typeAddr);
|
||||||
|
addr_ce GetReflectSpecializedType(addr_ce unspecializedType, addr_ce typeArgsSpanAddr);
|
||||||
|
addr_ce GetString(int stringId);
|
||||||
|
addr_ce GetConstantData(BeConstant* constant);
|
||||||
|
BfType* GetBfType(int typeId);
|
||||||
|
void PrepareConstStructEntry(CeConstStructData& constStructData);
|
||||||
|
bool CheckMemory(addr_ce addr, int32 size);
|
||||||
|
bool GetStringFromStringView(addr_ce addr, StringImpl& str);
|
||||||
|
bool GetCustomAttribute(BfCustomAttributes* customAttributes, int attributeTypeId, addr_ce resultAddr);
|
||||||
|
|
||||||
|
bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams = false);
|
||||||
|
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
||||||
|
BfIRValue CreateAttribute(BfAstNode* targetSrc, BfModule* module, BfIRConstHolder* constHolder, BfCustomAttribute* customAttribute);
|
||||||
|
|
||||||
|
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType);
|
||||||
|
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType);
|
||||||
|
};
|
||||||
|
|
||||||
class CeMachine
|
class CeMachine
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -624,63 +684,37 @@ public:
|
||||||
Dictionary<String, CeFunctionInfo*> mNamedFunctionMap;
|
Dictionary<String, CeFunctionInfo*> mNamedFunctionMap;
|
||||||
Dictionary<int, CeFunction*> mFunctionIdMap; // Only used for 32-bit
|
Dictionary<int, CeFunction*> mFunctionIdMap; // Only used for 32-bit
|
||||||
|
|
||||||
|
Array<CeContext*> mContextList;
|
||||||
|
|
||||||
BfCompiler* mCompiler;
|
BfCompiler* mCompiler;
|
||||||
BfModule* mCeModule;
|
BfModule* mCeModule;
|
||||||
int mRevision;
|
int mRevision;
|
||||||
int mRevisionExecuteTime;
|
int mRevisionExecuteTime;
|
||||||
int mExecuteId;
|
|
||||||
int mCurFunctionId;
|
int mCurFunctionId;
|
||||||
|
int mExecuteId;
|
||||||
// These are only valid for the current execution
|
|
||||||
ContiguousHeap* mHeap;
|
|
||||||
Array<CeFrame> mCallStack;
|
|
||||||
Array<uint8> mMemory;
|
|
||||||
Dictionary<int, addr_ce> mStringMap;
|
|
||||||
int mStringCharsOffset;
|
|
||||||
Dictionary<int, addr_ce> mReflectMap;
|
|
||||||
Dictionary<Val128, addr_ce> mConstDataMap;
|
|
||||||
Dictionary<String, CeStaticFieldInfo> mStaticFieldMap;
|
|
||||||
HashSet<int> mStaticCtorExecSet;
|
|
||||||
CeAppendAllocInfo* mAppendAllocInfo;
|
CeAppendAllocInfo* mAppendAllocInfo;
|
||||||
|
|
||||||
|
CeContext* mCurContext;
|
||||||
CeEmitContext* mCurEmitContext;
|
CeEmitContext* mCurEmitContext;
|
||||||
CeEvalFlags mCurEvalFlags;
|
|
||||||
CeBuilder* mCurBuilder;
|
CeBuilder* mCurBuilder;
|
||||||
CeFunction* mPreparingFunction;
|
CeFunction* mPreparingFunction;
|
||||||
CeFrame* mCurFrame;
|
|
||||||
BfAstNode* mCurTargetSrc;
|
BfParser* mTempParser;
|
||||||
BfMethodInstance* mCurMethodInstance;
|
BfReducer* mTempReducer;
|
||||||
BfModule* mCurModule;
|
BfPassInstance* mTempPassInstance;
|
||||||
BfType* mCurExpectingType;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CeMachine(BfCompiler* compiler);
|
CeMachine(BfCompiler* compiler);
|
||||||
~CeMachine();
|
~CeMachine();
|
||||||
|
|
||||||
BfError* Fail(const StringImpl& error);
|
|
||||||
BfError* Fail(const CeFrame& curFrame, const StringImpl& error);
|
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
uint8* CeMalloc(int size);
|
|
||||||
bool CeFree(addr_ce addr);
|
|
||||||
addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);
|
|
||||||
addr_ce GetReflectType(int typeId);
|
|
||||||
addr_ce GetString(int stringId);
|
|
||||||
addr_ce GetConstantData(BeConstant* constant);
|
|
||||||
BfType* GetBfType(int typeId);
|
|
||||||
void PrepareConstStructEntry(CeConstStructData& constStructData);
|
|
||||||
bool CheckMemory(addr_ce addr, int32 size);
|
|
||||||
bool GetStringFromStringView(addr_ce addr, StringImpl& str);
|
|
||||||
|
|
||||||
BeContext* GetBeContext();
|
BeContext* GetBeContext();
|
||||||
BeModule* GetBeModule();
|
BeModule* GetBeModule();
|
||||||
|
|
||||||
void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
|
void DerefMethodInfo(CeFunctionInfo* ceFunctionInfo);
|
||||||
void RemoveMethod(BfMethodInstance* methodInstance);
|
void RemoveMethod(BfMethodInstance* methodInstance);
|
||||||
bool WriteConstant(BfModule* module, addr_ce addr, BfConstant* constant, BfType* type, bool isParams = false);
|
|
||||||
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal);
|
|
||||||
BfIRValue CreateConstant(BfModule* module, uint8* ptr, BfType* type, BfType** outType = NULL);
|
|
||||||
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
void CreateFunction(BfMethodInstance* methodInstance, CeFunction* ceFunction);
|
||||||
bool Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* startFramePtr, BfType*& returnType);
|
CeErrorKind WriteConstant(CeConstStructData& data, BeConstant* constVal, CeContext* ceContext);
|
||||||
|
|
||||||
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
void PrepareFunction(CeFunction* methodInstance, CeBuilder* parentBuilder);
|
||||||
void MapFunctionId(CeFunction* ceFunction);
|
void MapFunctionId(CeFunction* ceFunction);
|
||||||
|
@ -699,6 +733,8 @@ public:
|
||||||
void SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue);
|
void SetAppendAllocInfo(BfModule* module, BfIRValue allocValue, BfIRValue appendSizeValue);
|
||||||
void ClearAppendAllocInfo();
|
void ClearAppendAllocInfo();
|
||||||
|
|
||||||
|
CeContext* AllocContext();
|
||||||
|
void ReleaseContext(CeContext* context);
|
||||||
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType);
|
BfTypedValue Call(BfAstNode* targetSrc, BfModule* module, BfMethodInstance* methodInstance, const BfSizedArray<BfIRValue>& args, CeEvalFlags flags, BfType* expectingType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
64
IDEHelper/Tests/src/Comptime.bf
Normal file
64
IDEHelper/Tests/src/Comptime.bf
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
class Comptime
|
||||||
|
{
|
||||||
|
[AttributeUsage(.All)]
|
||||||
|
struct IFaceAAttribute : Attribute, IComptimeTypeApply
|
||||||
|
{
|
||||||
|
String mMemberName;
|
||||||
|
int32 mInitVal;
|
||||||
|
|
||||||
|
public int32 InitVal
|
||||||
|
{
|
||||||
|
set mut
|
||||||
|
{
|
||||||
|
mInitVal = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(String memberName)
|
||||||
|
{
|
||||||
|
mMemberName = memberName;
|
||||||
|
mInitVal = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public void ApplyToType(Type type)
|
||||||
|
{
|
||||||
|
Compiler.EmitDefinition(type, scope $"""
|
||||||
|
public int32 m{mMemberName} = {mInitVal};
|
||||||
|
public int32 GetVal{mMemberName}() => mC;
|
||||||
|
""");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[IFaceA("C", InitVal=345)]
|
||||||
|
class ClassA
|
||||||
|
{
|
||||||
|
public int mA = 123;
|
||||||
|
|
||||||
|
[OnCompile(.TypeInit), Comptime]
|
||||||
|
public static void Generate()
|
||||||
|
{
|
||||||
|
Compiler.EmitDefinition(typeof(Self), """
|
||||||
|
public int32 mB = 234;
|
||||||
|
public int32 GetValB() => mB;
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public static void TestBasics()
|
||||||
|
{
|
||||||
|
ClassA ca = scope .();
|
||||||
|
Test.Assert(ca.mA == 123);
|
||||||
|
Test.Assert(ca.mB == 234);
|
||||||
|
Test.Assert(ca.GetValB() == 234);
|
||||||
|
Test.Assert(ca.mC == 345);
|
||||||
|
Test.Assert(ca.GetValC() == 345);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -211,9 +211,26 @@ namespace Tests
|
||||||
MethodA(list);
|
MethodA(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void MethodC()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MethodD(delegate void() dlg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void MethodD<T1>(delegate void(T1) dlg)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
MethodD(scope => MethodC);
|
||||||
|
|
||||||
List<Entry> list = scope .();
|
List<Entry> list = scope .();
|
||||||
list.Sort();
|
list.Sort();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue