mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Comptime EmitAddInterface
This commit is contained in:
parent
9f4a75dba3
commit
612368b0f7
6 changed files with 74 additions and 17 deletions
|
@ -257,6 +257,7 @@ namespace System
|
||||||
static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str);
|
static extern void* Comptime_MethodBuilder_EmitStr(void* native, StringView str);
|
||||||
static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags);
|
static extern void* Comptime_CreateMethod(int32 typeId, StringView methodName, Type returnType, MethodFlags methodFlags);
|
||||||
static extern void Comptime_EmitTypeBody(int32 typeId, StringView text);
|
static extern void Comptime_EmitTypeBody(int32 typeId, StringView text);
|
||||||
|
static extern void Comptime_EmitAddInterface(int32 typeId, int32 ifaceTypeId);
|
||||||
static extern void Comptime_EmitMethodEntry(int64 methodHandle, StringView text);
|
static extern void Comptime_EmitMethodEntry(int64 methodHandle, StringView text);
|
||||||
static extern void Comptime_EmitMethodExit(int64 methodHandle, StringView text);
|
static extern void Comptime_EmitMethodExit(int64 methodHandle, StringView text);
|
||||||
static extern void Comptime_EmitMixin(StringView text);
|
static extern void Comptime_EmitMixin(StringView text);
|
||||||
|
@ -275,6 +276,12 @@ namespace System
|
||||||
Comptime_EmitTypeBody((.)owner.TypeId, text);
|
Comptime_EmitTypeBody((.)owner.TypeId, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Comptime(OnlyFromComptime=true)]
|
||||||
|
public static void EmitAddInterface(Type owner, Type iface)
|
||||||
|
{
|
||||||
|
Comptime_EmitAddInterface((.)owner.TypeId, (.)iface.TypeId);
|
||||||
|
}
|
||||||
|
|
||||||
[Comptime(OnlyFromComptime=true)]
|
[Comptime(OnlyFromComptime=true)]
|
||||||
public static void EmitMethodEntry(ComptimeMethodInfo methodHandle, StringView text)
|
public static void EmitMethodEntry(ComptimeMethodInfo methodHandle, StringView text)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2076,6 +2076,9 @@ void BfModule::FinishCEParseContext(BfAstNode* refNode, BfTypeInstance* typeInst
|
||||||
|
|
||||||
void BfModule::UpdateCEEmit(CeEmitContext* ceEmitContext, BfTypeInstance* typeInstance, const StringImpl& ctxString, BfAstNode* refNode)
|
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())
|
if (ceEmitContext->mEmitData.IsEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3313,6 +3316,27 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
wantPopulateInterfaces = true;
|
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())
|
if (_CheckTypeDone())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -3703,12 +3727,22 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
PopulateType(innerType, BfPopulateType_Data);
|
PopulateType(innerType, BfPopulateType_Data);
|
||||||
|
|
||||||
auto innerTypeInst = innerType->ToTypeInstance();
|
auto innerTypeInst = innerType->ToTypeInstance();
|
||||||
if ((innerTypeInst != NULL) && (typeInstance->mTypeDef != innerTypeInst->mTypeDef))
|
if (innerTypeInst != NULL)
|
||||||
{
|
{
|
||||||
// Rebuild with proper typedef (generally from inner type comptime emission)
|
if (typeInstance->mTypeDef != innerTypeInst->mTypeDef)
|
||||||
typeInstance->mTypeDef = innerTypeInst->mTypeDef;
|
{
|
||||||
DoPopulateType(resolvedTypeRef, populateType);
|
// Rebuild with proper typedef (generally from inner type comptime emission)
|
||||||
return;
|
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;
|
auto baseType = typeInstance->mBaseType;
|
||||||
|
@ -4014,9 +4048,12 @@ void BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit) && (tryCE))
|
if ((typeInstance->mDefineState < BfTypeDefineState_CEPostTypeInit) && (tryCE))
|
||||||
{
|
{
|
||||||
BF_ASSERT(!typeInstance->mTypeDef->IsEmitted());
|
BF_ASSERT(!typeInstance->mTypeDef->IsEmitted());
|
||||||
|
|
||||||
|
if (typeInstance->mCeTypeInfo != NULL)
|
||||||
|
typeInstance->mCeTypeInfo->mPendingInterfaces.Clear();
|
||||||
|
|
||||||
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
typeInstance->mDefineState = BfTypeDefineState_CETypeInit;
|
||||||
bool hadNewMembers = false;
|
bool hadNewMembers = false;
|
||||||
DoCEEmit(typeInstance, hadNewMembers);
|
DoCEEmit(typeInstance, hadNewMembers);
|
||||||
|
@ -4071,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))
|
if ((typeInstance->mTypeDef->IsEmitted()) && (typeInstance->mCeTypeInfo == NULL))
|
||||||
{
|
{
|
||||||
BF_ASSERT(mCompiler->mCanceling);
|
BF_ASSERT(mCompiler->mCanceling);
|
||||||
|
@ -5676,15 +5716,6 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto matchedMethodDef = matchedMethod->mMethodDef;
|
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];
|
|
||||||
|
|
||||||
if (!matchedMethod->mIsForeignMethodDef)
|
if (!matchedMethod->mIsForeignMethodDef)
|
||||||
{
|
{
|
||||||
BfMethodInstanceGroup* boxedMethodInstanceGroup = &typeInstance->mMethodInstanceGroups[matchedMethod->mMethodDef->mIdx];
|
BfMethodInstanceGroup* boxedMethodInstanceGroup = &typeInstance->mMethodInstanceGroups[matchedMethod->mMethodDef->mIdx];
|
||||||
|
@ -5693,7 +5724,7 @@ void BfModule::DoTypeInstanceMethodProcessing(BfTypeInstance* typeInstance)
|
||||||
boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
|
boxedMethodInstanceGroup->mOnDemandKind = BfMethodOnDemandKind_Decl_AwaitingDecl;
|
||||||
VerifyOnDemandMethods();
|
VerifyOnDemandMethods();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None;
|
auto methodFlags = matchedMethod->mIsForeignMethodDef ? BfGetMethodInstanceFlag_ForeignMethodDef : BfGetMethodInstanceFlag_None;
|
||||||
methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly);
|
methodFlags = (BfGetMethodInstanceFlags)(methodFlags | BfGetMethodInstanceFlag_MethodInstanceOnly);
|
||||||
|
|
|
@ -1828,6 +1828,7 @@ class BfCeTypeInfo
|
||||||
public:
|
public:
|
||||||
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
|
Dictionary<int, BfCeTypeEmitEntry> mOnCompileMap;
|
||||||
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
|
Dictionary<int, BfCeTypeEmitEntry> mTypeIFaceMap;
|
||||||
|
Array<int> mPendingInterfaces;
|
||||||
Val128 mHash;
|
Val128 mHash;
|
||||||
bool mFailed;
|
bool mFailed;
|
||||||
BfCeTypeInfo* mNext;
|
BfCeTypeInfo* mNext;
|
||||||
|
|
|
@ -4740,6 +4740,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
||||||
return false;
|
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)
|
else if (checkFunction->mFunctionKind == CeFunctionKind_EmitMethodEntry)
|
||||||
{
|
{
|
||||||
int64 methodHandle = *(int64*)((uint8*)stackPtr);
|
int64 methodHandle = *(int64*)((uint8*)stackPtr);
|
||||||
|
@ -6833,6 +6844,10 @@ void CeMachine::CheckFunctionKind(CeFunction* ceFunction)
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody;
|
ceFunction->mFunctionKind = CeFunctionKind_EmitTypeBody;
|
||||||
}
|
}
|
||||||
|
if (methodDef->mName == "Comptime_EmitAddInterface")
|
||||||
|
{
|
||||||
|
ceFunction->mFunctionKind = CeFunctionKind_EmitAddInterface;
|
||||||
|
}
|
||||||
else if (methodDef->mName == "Comptime_EmitMethodEntry")
|
else if (methodDef->mName == "Comptime_EmitMethodEntry")
|
||||||
{
|
{
|
||||||
ceFunction->mFunctionKind = CeFunctionKind_EmitMethodEntry;
|
ceFunction->mFunctionKind = CeFunctionKind_EmitMethodEntry;
|
||||||
|
|
|
@ -289,6 +289,7 @@ enum CeFunctionKind
|
||||||
CeFunctionKind_Method_GetParamInfo,
|
CeFunctionKind_Method_GetParamInfo,
|
||||||
|
|
||||||
CeFunctionKind_EmitTypeBody,
|
CeFunctionKind_EmitTypeBody,
|
||||||
|
CeFunctionKind_EmitAddInterface,
|
||||||
CeFunctionKind_EmitMethodEntry,
|
CeFunctionKind_EmitMethodEntry,
|
||||||
CeFunctionKind_EmitMethodExit,
|
CeFunctionKind_EmitMethodExit,
|
||||||
CeFunctionKind_EmitMixin,
|
CeFunctionKind_EmitMixin,
|
||||||
|
@ -687,6 +688,7 @@ class CeEmitContext
|
||||||
public:
|
public:
|
||||||
BfType* mType;
|
BfType* mType;
|
||||||
BfMethodInstance* mMethodInstance;
|
BfMethodInstance* mMethodInstance;
|
||||||
|
Array<int32> mInterfaces;
|
||||||
String mEmitData;
|
String mEmitData;
|
||||||
String mExitEmitData;
|
String mExitEmitData;
|
||||||
bool mFailed;
|
bool mFailed;
|
||||||
|
|
|
@ -210,11 +210,12 @@ namespace Tests
|
||||||
}
|
}
|
||||||
|
|
||||||
Compiler.EmitTypeBody(type, scope $"{SERIALIZE_NAME}{{{serializeBuffer}\n}}\n");
|
Compiler.EmitTypeBody(type, scope $"{SERIALIZE_NAME}{{{serializeBuffer}\n}}\n");
|
||||||
|
Compiler.EmitAddInterface(type, typeof(ISerializable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
struct Foo : this(float x, float y), ISerializable
|
struct Foo : this(float x, float y)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue