mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Another pass at marking scoped raw arrays as deleted
This commit is contained in:
parent
81f8a95cd8
commit
76dfe97d78
5 changed files with 273 additions and 81 deletions
|
@ -140,23 +140,20 @@ namespace System
|
|||
#endif
|
||||
}
|
||||
|
||||
static void SetDeleted1(void* dest)
|
||||
{
|
||||
*((uint8*)dest) = 0xDD;
|
||||
}
|
||||
static void SetDeleted4(void* dest)
|
||||
{
|
||||
*((uint32*)dest) = 0xDDDDDDDD;
|
||||
}
|
||||
static void SetDeleted8(void* dest)
|
||||
{
|
||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
||||
}
|
||||
static void SetDeleted16(void* dest)
|
||||
{
|
||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
||||
*((uint64*)dest + 1) = 0xDDDDDDDDDDDDDDDDUL;
|
||||
}
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted1(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted4(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted8(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted16(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static extern void SetDeletedX(void* dest, int size);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static extern void SetDeleted(void* dest, int size, int32 align, int arrayCount);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static extern void SetDeletedArray(void* dest, int size, int32 align, int arrayCount);
|
||||
|
||||
public static int MemCmp(void* memA, void* memB, int length)
|
||||
{
|
||||
|
|
|
@ -118,23 +118,20 @@ namespace System
|
|||
#endif
|
||||
}
|
||||
|
||||
static void SetDeleted1(void* dest)
|
||||
{
|
||||
*((uint8*)dest) = 0xDD;
|
||||
}
|
||||
static void SetDeleted4(void* dest)
|
||||
{
|
||||
*((uint32*)dest) = 0xDDDDDDDD;
|
||||
}
|
||||
static void SetDeleted8(void* dest)
|
||||
{
|
||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
||||
}
|
||||
static void SetDeleted16(void* dest)
|
||||
{
|
||||
*((uint64*)dest) = 0xDDDDDDDDDDDDDDDDUL;
|
||||
*((uint64*)dest + 1) = 0xDDDDDDDDDDDDDDDDUL;
|
||||
}
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted1(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted4(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted8(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static void SetDeleted16(void* dest);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static extern void SetDeletedX(void* dest, int size);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static extern void SetDeleted(void* dest, int size, int32 align, int arrayCount);
|
||||
[Error("Cannot be called directly"), SkipCall]
|
||||
static extern void SetDeletedArray(void* dest, int size, int32 align, int arrayCount);
|
||||
|
||||
public static int MemCmp(void* memA, void* memB, int length)
|
||||
{
|
||||
|
|
|
@ -1809,7 +1809,7 @@ BfIRValue BfModule::CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime,
|
|||
return allocaInst;
|
||||
}
|
||||
|
||||
void BfModule::AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData* scopeData, bool condAlloca, bool mayEscape)
|
||||
void BfModule::AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scopeData, bool condAlloca, bool mayEscape)
|
||||
{
|
||||
//This was removed because we want the alloc to be added to the __deferred list if it's actually a "stack"
|
||||
// 'stack' in a head scopeData is really the same as 'scopeData', so use the simpler scopeData handling
|
||||
|
@ -1869,41 +1869,84 @@ void BfModule::AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData*
|
|||
//TODO: In the future we could be smarter about statically determining that our value hasn't escaped and eliding this
|
||||
if (mayEscape)
|
||||
{
|
||||
// Is this worth it?
|
||||
// if ((!IsOptimized()) && (val.mType->IsComposite()) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly))
|
||||
// {
|
||||
// auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr);
|
||||
// bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData);
|
||||
// if (!isDyn)
|
||||
// {
|
||||
// int clearSize = val.mType->mSize;
|
||||
// BfModuleMethodInstance dtorMethodInstance = GetInternalMethod("MemSet");
|
||||
// BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
||||
// SizedArray<BfIRValue, 1> llvmArgs;
|
||||
// llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||
// llvmArgs.push_back(GetConstValue8(0xDD));
|
||||
// llvmArgs.push_back(GetConstValue(clearSize));
|
||||
// llvmArgs.push_back(GetConstValue32(val.mType->mAlign));
|
||||
// llvmArgs.push_back(mBfIRBuilder->CreateConst(BfTypeCode_Boolean, 0));
|
||||
// AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// const char* funcName = "SetDeleted1";
|
||||
// if (val.mType->mSize >= 16)
|
||||
// funcName = "SetDeleted16";
|
||||
// else if (val.mType->mSize >= 8)
|
||||
// funcName = "SetDeleted8";
|
||||
// else if (val.mType->mSize >= 4)
|
||||
// funcName = "SetDeleted4";
|
||||
//
|
||||
// BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(funcName);
|
||||
// BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
||||
// SizedArray<BfIRValue, 1> llvmArgs;
|
||||
// llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||
// AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||
// }
|
||||
// }
|
||||
|
||||
if ((!IsOptimized()) && (!val.mType->IsValuelessType()) && (!mBfIRBuilder->mIgnoreWrites) && (!mCompiler->mIsResolveOnly))
|
||||
{
|
||||
auto nullPtrType = GetPrimitiveType(BfTypeCode_NullPtr);
|
||||
bool isDyn = mCurMethodState->mCurScope->IsDyn(scopeData);
|
||||
if (!isDyn)
|
||||
{
|
||||
const char* methodName = arraySize ? "SetDeletedArray" : "SetDeleted";
|
||||
BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName);
|
||||
BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
||||
if (!dtorMethodInstance.mMethodInstance)
|
||||
{
|
||||
Fail(StrFormat("Unable to find %s", methodName));
|
||||
}
|
||||
else
|
||||
{
|
||||
SizedArray<BfIRValue, 1> llvmArgs;
|
||||
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||
llvmArgs.push_back(GetConstValue(val.mType->mSize));
|
||||
llvmArgs.push_back(GetConstValue32(val.mType->mAlign));
|
||||
if (arraySize)
|
||||
llvmArgs.push_back(arraySize);
|
||||
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((arraySize) && (!arraySize.IsConst()) && (val.mType->mSize < mSystem->mPtrSize))
|
||||
{
|
||||
BfIRValue clearSize = arraySize;
|
||||
if (val.mType->GetStride() > 1)
|
||||
clearSize = mBfIRBuilder->CreateMul(clearSize, GetConstValue(val.mType->GetStride()));
|
||||
|
||||
const char* methodName = "SetDeletedX";
|
||||
BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(methodName);
|
||||
BF_ASSERT(dtorMethodInstance);
|
||||
if (!dtorMethodInstance)
|
||||
{
|
||||
Fail(StrFormat("Unable to find %s", methodName));
|
||||
}
|
||||
else
|
||||
{
|
||||
SizedArray<BfIRValue, 1> llvmArgs;
|
||||
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||
llvmArgs.push_back(clearSize);
|
||||
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
intptr clearSize = val.mType->mSize;
|
||||
auto constant = mBfIRBuilder->GetConstant(arraySize);
|
||||
if (constant != NULL)
|
||||
clearSize = (intptr)(clearSize * constant->mInt64);
|
||||
|
||||
const char* funcName = "SetDeleted1";
|
||||
if (clearSize >= 16)
|
||||
funcName = "SetDeleted16";
|
||||
else if (clearSize >= 8)
|
||||
funcName = "SetDeleted8";
|
||||
else if (clearSize >= 4)
|
||||
funcName = "SetDeleted4";
|
||||
|
||||
BfModuleMethodInstance dtorMethodInstance = GetInternalMethod(funcName);
|
||||
BF_ASSERT(dtorMethodInstance.mMethodInstance != NULL);
|
||||
if (!dtorMethodInstance)
|
||||
{
|
||||
Fail(StrFormat("Unable to find %s", funcName));
|
||||
}
|
||||
else
|
||||
{
|
||||
SizedArray<BfIRValue, 1> llvmArgs;
|
||||
llvmArgs.push_back(mBfIRBuilder->CreateBitCast(val.mValue, mBfIRBuilder->MapType(nullPtrType)));
|
||||
AddDeferredCall(dtorMethodInstance, llvmArgs, scopeData, refNode, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3904,6 +3947,8 @@ void BfModule::CreateFakeCallerMethod(const String& funcName)
|
|||
{
|
||||
if (mCurMethodInstance->mHasFailed)
|
||||
return;
|
||||
if (mCurMethodInstance->mMethodDef->mIsSkipCall)
|
||||
return;
|
||||
|
||||
BF_ASSERT(mCurMethodInstance->mIRFunction);
|
||||
|
||||
|
@ -7809,7 +7854,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
mBfIRBuilder->SetInsertPoint(clearBlock);
|
||||
}
|
||||
|
||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
||||
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
|
||||
|
||||
if (!isConstSize)
|
||||
{
|
||||
|
@ -7839,7 +7884,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
auto loadedPtr = _CreateDynAlloc(sizeValue, arrayType->mAlign);
|
||||
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapType(arrayType)), arrayType);
|
||||
if (!noDtorCall)
|
||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
||||
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
|
||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||
return typedVal.mValue;
|
||||
}
|
||||
|
@ -7878,7 +7923,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
if (!isDynAlloc)
|
||||
mBfIRBuilder->SetInsertPoint(prevBlock);
|
||||
if (!noDtorCall)
|
||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
||||
AddStackAlloc(typedVal, arraySize, NULL, scopeData, false, true);
|
||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||
return typedVal.mValue;
|
||||
}
|
||||
|
@ -7898,7 +7943,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
auto loadedPtr = _CreateDynAlloc(sizeValue, typeInstance->mAlign);
|
||||
auto typedVal = BfTypedValue(mBfIRBuilder->CreateBitCast(loadedPtr, mBfIRBuilder->MapTypeInstPtr(typeInstance)), typeInstance);
|
||||
if (!noDtorCall)
|
||||
AddStackAlloc(typedVal, NULL, scopeData, mCurMethodState->mInConditionalBlock, true);
|
||||
AddStackAlloc(typedVal, arraySize, NULL, scopeData, mCurMethodState->mInConditionalBlock, true);
|
||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||
return typedVal.mValue;
|
||||
}
|
||||
|
@ -7965,7 +8010,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
bool doCondAlloca = false;
|
||||
if (!IsTargetingBeefBackend())
|
||||
doCondAlloca = !wasDynAlloc && isDynAlloc && mCurMethodState->mInConditionalBlock;
|
||||
AddStackAlloc(typedVal, NULL, scopeData, doCondAlloca, true);
|
||||
AddStackAlloc(typedVal, arraySize, NULL, scopeData, doCondAlloca, true);
|
||||
}
|
||||
InitTypeInst(typedVal, scopeData, zeroMemory, sizeValue);
|
||||
|
||||
|
@ -8009,7 +8054,7 @@ BfIRValue BfModule::AllocFromType(BfType* type, const BfAllocTarget& allocTarget
|
|||
}
|
||||
}
|
||||
if (!noDtorCall)
|
||||
AddStackAlloc(typedVal, NULL, scopeData, false, true);
|
||||
AddStackAlloc(typedVal, BfIRValue(), NULL, scopeData, false, true);
|
||||
if (typeInstance != NULL)
|
||||
{
|
||||
InitTypeInst(typedVal, scopeData, zeroMemory, GetConstValue(typeInstance->mInstSize));
|
||||
|
|
|
@ -1468,7 +1468,7 @@ public:
|
|||
void NewScopeState(bool createLexicalBlock = true, bool flushValueScope = true); // returns prev scope data
|
||||
BfIRValue CreateAlloca(BfType* type, bool addLifetime = true, const char* name = NULL, BfIRValue arraySize = BfIRValue());
|
||||
BfIRValue CreateAllocaInst(BfTypeInstance* typeInst, bool addLifetime = true, const char* name = NULL);
|
||||
void AddStackAlloc(BfTypedValue val, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false);
|
||||
void AddStackAlloc(BfTypedValue val, BfIRValue arraySize, BfAstNode* refNode, BfScopeData* scope, bool condAlloca = false, bool mayEscape = false);
|
||||
void RestoreScoreState_LocalVariables();
|
||||
void RestoreScopeState();
|
||||
void MarkDynStack(BfScopeData* scope);
|
||||
|
|
|
@ -540,6 +540,160 @@ BfDeferredCallEntry* BfModule::AddDeferredCall(const BfModuleMethodInstance& mod
|
|||
|
||||
void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfDeferredBlockFlags flags)
|
||||
{
|
||||
if (moduleMethodInstance.mMethodInstance->GetOwner()->IsInstanceOf(mCompiler->mInternalTypeDef))
|
||||
{
|
||||
if (moduleMethodInstance.mMethodInstance->mMethodDef->mName.StartsWith("SetDeleted"))
|
||||
{
|
||||
intptr typeSize = 0;
|
||||
intptr typeAlign = 1;
|
||||
intptr clearSize = 0;
|
||||
bool isDynSize = false;
|
||||
|
||||
bool mayBeZero = false;
|
||||
auto ptrValue = llvmArgs[0];
|
||||
BfIRValue arraySize;
|
||||
|
||||
if ((moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted") ||
|
||||
(moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeletedArray"))
|
||||
{
|
||||
auto constant = mBfIRBuilder->GetConstant(llvmArgs[1]);
|
||||
if (constant != NULL)
|
||||
typeSize = constant->mInt64;
|
||||
constant = mBfIRBuilder->GetConstant(llvmArgs[2]);
|
||||
if (constant != NULL)
|
||||
typeAlign = constant->mInt64;
|
||||
auto arraySize = llvmArgs[3];
|
||||
|
||||
intptr allocSize = typeSize;
|
||||
if (arraySize)
|
||||
{
|
||||
allocSize = BF_ALIGN(typeSize, typeAlign);
|
||||
auto constant = mBfIRBuilder->GetConstant(arraySize);
|
||||
if (constant != NULL)
|
||||
allocSize = allocSize * (intptr)constant->mInt64;
|
||||
else
|
||||
{
|
||||
isDynSize = true;
|
||||
mayBeZero = true;
|
||||
}
|
||||
}
|
||||
|
||||
clearSize = BF_MIN(allocSize, mSystem->mPtrSize);
|
||||
}
|
||||
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeletedX")
|
||||
{
|
||||
// Note: this infers that mayBeZero is false still, because the deferred call would not have
|
||||
// been added if the array size was zero
|
||||
typeSize = 1;
|
||||
clearSize = typeSize;
|
||||
arraySize = llvmArgs[1];
|
||||
isDynSize = true;
|
||||
}
|
||||
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted1")
|
||||
{
|
||||
clearSize = 1;
|
||||
}
|
||||
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted2")
|
||||
{
|
||||
clearSize = 2;
|
||||
}
|
||||
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted4")
|
||||
{
|
||||
clearSize = 4;
|
||||
}
|
||||
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted8")
|
||||
{
|
||||
clearSize = 8;
|
||||
}
|
||||
else if (moduleMethodInstance.mMethodInstance->mMethodDef->mName == "SetDeleted16")
|
||||
{
|
||||
clearSize = 16;
|
||||
}
|
||||
|
||||
if (clearSize > 0)
|
||||
{
|
||||
BfTypeCode clearTypeCode = BfTypeCode_Int8;
|
||||
if (clearSize >= mSystem->mPtrSize)
|
||||
clearTypeCode = BfTypeCode_IntPtr;
|
||||
else if (clearSize >= 4)
|
||||
clearTypeCode = BfTypeCode_Int32;
|
||||
else if (clearSize >= 2)
|
||||
clearTypeCode = BfTypeCode_Int16;
|
||||
|
||||
auto intType = GetPrimitiveType(clearTypeCode);
|
||||
auto intPtrType = CreatePointerType(intType);
|
||||
|
||||
if (isDynSize)
|
||||
{
|
||||
if (clearSize >= mSystem->mPtrSize)
|
||||
{
|
||||
auto ddSize1Block = mBfIRBuilder->CreateBlock("DDSize1");
|
||||
auto ddDoneBlock = mBfIRBuilder->CreateBlock("DDDone");
|
||||
|
||||
auto cmp = mBfIRBuilder->CreateCmpGT(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), true);
|
||||
mBfIRBuilder->CreateCondBr(cmp, ddSize1Block, ddDoneBlock);
|
||||
|
||||
mBfIRBuilder->AddBlock(ddSize1Block);
|
||||
mBfIRBuilder->SetInsertPoint(ddSize1Block);
|
||||
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
|
||||
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
|
||||
mBfIRBuilder->CreateBr(ddDoneBlock);
|
||||
|
||||
mBfIRBuilder->AddBlock(ddDoneBlock);
|
||||
mBfIRBuilder->SetInsertPoint(ddDoneBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we allocate at least this many then we can do an IntPtr-sized marking, otherwise just one element's worth
|
||||
int intPtrCount = (int)((mSystem->mPtrSize + typeSize - 1) / typeSize);
|
||||
|
||||
BfIRBlock ddSizePtrBlock = mBfIRBuilder->CreateBlock("DDSizePtr");
|
||||
BfIRBlock ddCheck1Block = mBfIRBuilder->CreateBlock("DDCheck1");
|
||||
BfIRBlock ddSize1Block;
|
||||
if (mayBeZero)
|
||||
ddSize1Block = mBfIRBuilder->CreateBlock("DDSize1");
|
||||
BfIRBlock ddDoneBlock = mBfIRBuilder->CreateBlock("DDDone");
|
||||
|
||||
auto intptrType = GetPrimitiveType(BfTypeCode_IntPtr);
|
||||
auto intptrPtrType = CreatePointerType(intptrType);
|
||||
|
||||
auto cmpPtr = mBfIRBuilder->CreateCmpGTE(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, intPtrCount), true);
|
||||
mBfIRBuilder->CreateCondBr(cmpPtr, ddSizePtrBlock, ddCheck1Block);
|
||||
|
||||
mBfIRBuilder->AddBlock(ddSizePtrBlock);
|
||||
mBfIRBuilder->SetInsertPoint(ddSizePtrBlock);
|
||||
auto intptrPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intptrPtrType));
|
||||
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0xDDDDDDDDDDDDDDDDULL), intptrPtrVal);
|
||||
mBfIRBuilder->CreateBr(ddDoneBlock);
|
||||
|
||||
mBfIRBuilder->AddBlock(ddCheck1Block);
|
||||
mBfIRBuilder->SetInsertPoint(ddCheck1Block);
|
||||
if (mayBeZero)
|
||||
{
|
||||
auto cmp1 = mBfIRBuilder->CreateCmpGT(arraySize, mBfIRBuilder->CreateConst(BfTypeCode_IntPtr, 0), true);
|
||||
mBfIRBuilder->CreateCondBr(cmp1, ddSize1Block, ddDoneBlock);
|
||||
|
||||
mBfIRBuilder->AddBlock(ddSize1Block);
|
||||
mBfIRBuilder->SetInsertPoint(ddSize1Block);
|
||||
}
|
||||
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
|
||||
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
|
||||
mBfIRBuilder->CreateBr(ddDoneBlock);
|
||||
|
||||
mBfIRBuilder->AddBlock(ddDoneBlock);
|
||||
mBfIRBuilder->SetInsertPoint(ddDoneBlock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto intPtrVal = mBfIRBuilder->CreateBitCast(ptrValue, mBfIRBuilder->MapType(intPtrType));
|
||||
mBfIRBuilder->CreateStore(mBfIRBuilder->CreateConst(clearTypeCode, 0xDDDDDDDDDDDDDDDDULL), intPtrVal);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (moduleMethodInstance.mMethodInstance == mContext->mValueTypeDeinitSentinel)
|
||||
{
|
||||
BF_ASSERT(llvmArgs.size() == 3);
|
||||
|
@ -660,7 +814,6 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry)
|
|||
return;
|
||||
}
|
||||
|
||||
auto moduleMethodInstance = deferredCallEntry.mModuleMethodInstance;
|
||||
auto args = deferredCallEntry.mScopeArgs;
|
||||
if (deferredCallEntry.mArgsNeedLoad)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue