mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 11:38:21 +02:00
Optimizations, switching CanImplicitlyCast method, new CPU rate checker
This commit is contained in:
parent
39fd8d2624
commit
098ad1ce55
25 changed files with 759 additions and 301 deletions
|
@ -51,7 +51,7 @@ namespace System
|
|||
{
|
||||
if (mData & sIsEnumerating != 0)
|
||||
{
|
||||
Enumerator* enumerator = (Enumerator*)(mData & sDataMask);
|
||||
Enumerator* enumerator = (Enumerator*)(void*)(mData & sDataMask);
|
||||
return enumerator.[Friend]mTarget;
|
||||
}
|
||||
return Internal.UnsafeCastToObject((void*)mData);
|
||||
|
@ -61,7 +61,7 @@ namespace System
|
|||
{
|
||||
if (mData & sIsEnumerating != 0)
|
||||
{
|
||||
Enumerator* enumerator = (Enumerator*)(mData & sDataMask);
|
||||
Enumerator* enumerator = (Enumerator*)(void*)(mData & sDataMask);
|
||||
enumerator.[Friend]mTarget = value;
|
||||
}
|
||||
else
|
||||
|
@ -249,12 +249,12 @@ namespace System
|
|||
if (mEvent.mData & sIsEnumerating == 0)
|
||||
{
|
||||
mTarget = mEvent.Target;
|
||||
mEvent.mData = (int)(&this) | sIsEnumerating;
|
||||
mEvent.mData = (int)(void*)(&this) | sIsEnumerating;
|
||||
mRootEnumerator = &this;
|
||||
}
|
||||
else
|
||||
{
|
||||
mRootEnumerator = (Enumerator*)(mEvent.mData & Event<T>.sDataMask);
|
||||
mRootEnumerator = (Enumerator*)(void*)(mEvent.mData & Event<T>.sDataMask);
|
||||
}
|
||||
mIdx = -1;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ namespace System.IO
|
|||
if (sCurrentThis.mSelectedPath.Length != 0)
|
||||
{
|
||||
// Try to select the folder specified by selectedPath
|
||||
Windows.SendMessageW(hWnd, Windows.BFFM_SETSELECTIONA, 1, (int)sCurrentThis.mSelectedPath.ToScopedNativeWChar!());
|
||||
Windows.SendMessageW(hWnd, Windows.BFFM_SETSELECTIONA, 1, (int)(void*)sCurrentThis.mSelectedPath.ToScopedNativeWChar!());
|
||||
}
|
||||
break;
|
||||
case Windows.BFFM_SELCHANGED:
|
||||
|
|
|
@ -438,7 +438,7 @@ namespace System.IO
|
|||
{
|
||||
using (sMonitor.Enter())
|
||||
{
|
||||
var ofn = (Windows.OpenFileName*)lparam;
|
||||
var ofn = (Windows.OpenFileName*)(void*)lparam;
|
||||
sHookMap[(int)hWnd] = (CommonDialog)Internal.UnsafeCastToObject((void*)ofn.mCustData);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace System
|
|||
{
|
||||
Type type;
|
||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||
ClassVData* maskedVData = (ClassVData*)(mClassVData & ~(int)0xFF);
|
||||
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||
type = maskedVData.mType;
|
||||
#else
|
||||
type = mClassVData.mType;
|
||||
|
@ -63,7 +63,7 @@ namespace System
|
|||
{
|
||||
Type type;
|
||||
#if BF_ENABLE_OBJECT_DEBUG_FLAGS
|
||||
ClassVData* maskedVData = (ClassVData*)(mClassVData & ~(int)0xFF);
|
||||
ClassVData* maskedVData = (ClassVData*)(void*)(mClassVData & ~(int)0xFF);
|
||||
type = maskedVData.mType;
|
||||
#else
|
||||
type = mClassVData.mType;
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace System
|
|||
|
||||
public int GetHashCode()
|
||||
{
|
||||
return (int)mVal;
|
||||
return (int)(void*)mVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1566,7 +1566,7 @@ namespace BeefPerf
|
|||
uint32 tickMSNow = (.)ReadSLEB128();
|
||||
int64 clockRate = (.)ReadSLEB128();
|
||||
|
||||
mTicksToUSScale = 1000.0 / clockRate;
|
||||
mTicksToUSScale = 1000000.0 / clockRate;
|
||||
|
||||
/*if (mFirstTimeStamp == -1)
|
||||
{
|
||||
|
|
|
@ -909,8 +909,25 @@ static void __cdecl AbortHandler(int)
|
|||
BfpSystem_FatalError("Abort handler", NULL);
|
||||
}
|
||||
|
||||
static int64 gCPUFreq = -1;
|
||||
static int64 gStartCPUTick = -1;
|
||||
static int64 gStartQPF = -1;
|
||||
|
||||
static void InitCPUFreq()
|
||||
{
|
||||
if (gStartCPUTick == -1)
|
||||
{
|
||||
gStartCPUTick = __rdtsc();
|
||||
LARGE_INTEGER largeVal = { 0 };
|
||||
QueryPerformanceCounter(&largeVal);
|
||||
gStartQPF = largeVal.QuadPart;
|
||||
}
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags)
|
||||
{
|
||||
InitCPUFreq();
|
||||
|
||||
::_set_error_mode(_OUT_TO_STDERR);
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
@ -1124,9 +1141,27 @@ BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTick()
|
|||
|
||||
BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTickFreq()
|
||||
{
|
||||
LARGE_INTEGER freq = { 0 };
|
||||
QueryPerformanceFrequency(&freq);
|
||||
return freq.QuadPart;
|
||||
LARGE_INTEGER largeVal = { 0 };
|
||||
QueryPerformanceFrequency(&largeVal);
|
||||
int64 qpfFreq = largeVal.QuadPart;
|
||||
|
||||
if (gStartCPUTick == -1)
|
||||
{
|
||||
InitCPUFreq();
|
||||
Sleep(10);
|
||||
}
|
||||
|
||||
int64 cpuTick1 = __rdtsc();
|
||||
QueryPerformanceCounter(&largeVal);
|
||||
int64 slowTick1 = largeVal.QuadPart;
|
||||
|
||||
int64 cpuElapsed = cpuTick1 - gStartCPUTick;
|
||||
int64 slowElapsed = slowTick1 - gStartQPF;
|
||||
double elapsedSeconds = slowElapsed / (double)qpfFreq;
|
||||
int64 freq = (int64)(cpuElapsed / elapsedSeconds);
|
||||
gCPUFreq = freq;
|
||||
|
||||
return gCPUFreq;
|
||||
}
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_CreateGUID(BfpGUID* outGuid)
|
||||
|
|
|
@ -639,7 +639,7 @@ public:
|
|||
this->mSize++;
|
||||
}
|
||||
|
||||
void Insert(intptr idx, T* vals, intptr size)
|
||||
void Insert(intptr idx, const T* vals, intptr size)
|
||||
{
|
||||
BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
|
||||
if (this->mSize + size > this->mAllocSize)
|
||||
|
@ -934,7 +934,7 @@ public:
|
|||
this->mSize++;
|
||||
}
|
||||
|
||||
void Insert(intptr idx, T* vals, intptr size)
|
||||
void Insert(intptr idx, const T* vals, intptr size)
|
||||
{
|
||||
BF_ASSERT((uintptr)idx <= (uintptr)this->mSize);
|
||||
if (this->mSize + size > this->mAllocSize)
|
||||
|
|
|
@ -355,7 +355,7 @@ static int64 GetTimestamp()
|
|||
#ifdef BF_PLATFORM_WINDOWS
|
||||
return __rdtsc() / 100;
|
||||
#else
|
||||
return BfpSystem_GetCPUTick();
|
||||
return BfpSystem_GetCPUTick() / 100;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -186,7 +186,7 @@ public:
|
|||
return mPrevSizes + (int)((uint8*)ptr - mCurAlloc);
|
||||
}
|
||||
|
||||
uint8* AllocBytes(int wantSize, int alignSize, const char* dbgName = "AllocBytes")
|
||||
uint8* AllocBytes(intptr wantSize, int alignSize, const char* dbgName = "AllocBytes")
|
||||
{
|
||||
mCurPtr = (uint8*)(((intptr)mCurPtr + alignSize - 1) & ~(alignSize - 1));
|
||||
|
||||
|
@ -194,7 +194,7 @@ public:
|
|||
return retVal;
|
||||
}
|
||||
|
||||
uint8* AllocBytes(int wantSize, const char* dbgName = "AllocBytes")
|
||||
uint8* AllocBytes(intptr wantSize, const char* dbgName = "AllocBytes")
|
||||
{
|
||||
#ifdef BUMPALLOC_TRACKALLOCS
|
||||
BumpAllocTrackedEntry* allocSizePtr;
|
||||
|
@ -237,6 +237,11 @@ class AllocatorBump
|
|||
public:
|
||||
BumpAllocator* mAlloc;
|
||||
|
||||
AllocatorBump()
|
||||
{
|
||||
mAlloc = NULL;
|
||||
}
|
||||
|
||||
T* allocate(intptr count)
|
||||
{
|
||||
return (T*)mAlloc->AllocBytes((int)(sizeof(T) * count), alignof(T));
|
||||
|
@ -245,6 +250,16 @@ public:
|
|||
void deallocate(T* ptr)
|
||||
{
|
||||
}
|
||||
|
||||
void* rawAllocate(intptr size)
|
||||
{
|
||||
return mAlloc->AllocBytes(size, 16);
|
||||
}
|
||||
|
||||
void rawDeallocate(void* ptr)
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -107,6 +107,42 @@ void ChunkedDataBuffer::Write(uint8 byte)
|
|||
mSize++;
|
||||
}
|
||||
|
||||
void ChunkedDataBuffer::Write_2(uint16 val)
|
||||
{
|
||||
while (mWriteCurPtr + 2 > mWriteCurAlloc + ALLOC_SIZE)
|
||||
{
|
||||
Write((uint8*)&val, 2);
|
||||
return;
|
||||
}
|
||||
*(uint16*)mWriteCurPtr = val;
|
||||
mWriteCurPtr += 2;
|
||||
mSize += 2;
|
||||
}
|
||||
|
||||
void ChunkedDataBuffer::Write_3(uint32 val)
|
||||
{
|
||||
while (mWriteCurPtr + 3 > mWriteCurAlloc + ALLOC_SIZE)
|
||||
{
|
||||
Write((uint8*)&val, 3);
|
||||
return;
|
||||
}
|
||||
*(uint32*)mWriteCurPtr = val;
|
||||
mWriteCurPtr += 3;
|
||||
mSize += 3;
|
||||
}
|
||||
|
||||
void ChunkedDataBuffer::Write_4(uint32 val)
|
||||
{
|
||||
while (mWriteCurPtr + 4 > mWriteCurAlloc + ALLOC_SIZE)
|
||||
{
|
||||
Write((uint8*)&val, 4);
|
||||
return;
|
||||
}
|
||||
*(uint32*)mWriteCurPtr = val;
|
||||
mWriteCurPtr += 4;
|
||||
mSize += 4;
|
||||
}
|
||||
|
||||
int ChunkedDataBuffer::GetReadPos()
|
||||
{
|
||||
return mReadPoolIdx * ALLOC_SIZE + (int)(mReadCurPtr - mReadCurAlloc);
|
||||
|
|
|
@ -32,6 +32,9 @@ public:
|
|||
void GrowPool();
|
||||
void Write(const void* data, int size);
|
||||
void Write(uint8 byte);
|
||||
void Write_2(uint16 val);
|
||||
void Write_3(uint32 val);
|
||||
void Write_4(uint32 val);
|
||||
int GetReadPos();
|
||||
void SetReadPos(int pos);
|
||||
void NextReadPool();
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "../Common.h"
|
||||
#include "Array.h"
|
||||
#include <unordered_map>
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
template <typename TKey>
|
||||
class HashSet
|
||||
template <typename TKey, typename TAlloc = AllocatorCLib<TKey> >
|
||||
class HashSet : public TAlloc
|
||||
{
|
||||
public:
|
||||
typedef int int_cosize;
|
||||
|
@ -254,14 +254,14 @@ private:
|
|||
Resize(ExpandSize(mCount), false);
|
||||
}
|
||||
|
||||
void Resize(int newSize, bool forceNewHashCodes)
|
||||
void Resize(intptr newSize, bool forceNewHashCodes)
|
||||
{
|
||||
BF_ASSERT(newSize >= mAllocSize);
|
||||
int_cosize* newBuckets = new int_cosize[newSize];
|
||||
int_cosize* newBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * newSize);
|
||||
for (int_cosize i = 0; i < newSize; i++)
|
||||
newBuckets[i] = -1;
|
||||
Entry* newEntries = new Entry[newSize];
|
||||
//mEntries.CopyTo(newEntries, 0, 0, mCount);
|
||||
Entry* newEntries = (Entry*)rawAllocate(sizeof(Entry)*newSize);
|
||||
|
||||
for (int i = 0; i < mCount; i++)
|
||||
{
|
||||
auto& newEntry = newEntries[i];
|
||||
|
@ -294,12 +294,12 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
delete[] mBuckets;
|
||||
delete[] mEntries;
|
||||
rawDeallocate(mBuckets);
|
||||
rawDeallocate(mEntries);
|
||||
|
||||
mBuckets = newBuckets;
|
||||
mEntries = newEntries;
|
||||
mAllocSize = newSize;
|
||||
mAllocSize = (int_cosize)newSize;
|
||||
}
|
||||
|
||||
int FindEntry(const TKey& key)
|
||||
|
@ -332,10 +332,10 @@ private:
|
|||
void Initialize(intptr capacity)
|
||||
{
|
||||
int_cosize size = GetPrimeish((int_cosize)capacity);
|
||||
mBuckets = new int_cosize[size];
|
||||
mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * size);
|
||||
mAllocSize = size;
|
||||
for (int_cosize i = 0; i < (int_cosize)mAllocSize; i++) mBuckets[i] = -1;
|
||||
mEntries = new Entry[size];
|
||||
mEntries = (Entry*)rawAllocate(sizeof(Entry) * size);
|
||||
mFreeList = -1;
|
||||
}
|
||||
|
||||
|
@ -431,8 +431,8 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
mBuckets = new int_cosize[mAllocSize];
|
||||
mEntries = new Entry[mAllocSize];
|
||||
mBuckets = (int_cosize*)rawAllocate(sizeof(int_cosize) * mAllocSize);
|
||||
mEntries = (Entry*)rawAllocate(sizeof(Entry) * mAllocSize);
|
||||
|
||||
for (int_cosize i = 0; i < mAllocSize; i++)
|
||||
mBuckets[i] = val.mBuckets[i];
|
||||
|
@ -476,8 +476,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
delete[] mBuckets;
|
||||
delete[] mEntries;
|
||||
rawDeallocate(mBuckets);
|
||||
rawDeallocate(mEntries);
|
||||
}
|
||||
|
||||
HashSet& operator=(const HashSet& rhs)
|
||||
|
|
|
@ -288,6 +288,11 @@ public:
|
|||
this->mSize = 0;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
this->mSize = 0;
|
||||
}
|
||||
|
||||
/*void Free()
|
||||
{
|
||||
if (this->mVals != NULL)
|
||||
|
@ -1060,17 +1065,27 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
static bool operator==(const ArrayBase<T>& arrA, const SizedArrayBase<T>& arrB)
|
||||
{
|
||||
if (arrA.mSize != arrB.mSize)
|
||||
return false;
|
||||
for (intptr i = 0; i < arrA.mSize; i++)
|
||||
if (arrA.mVals[i] != arrB.mVals[i])
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_BF_END;
|
||||
|
||||
/*namespace std
|
||||
namespace std
|
||||
{
|
||||
template<typename T>
|
||||
struct hash<Beefy::Array<T> >
|
||||
struct hash<Beefy::SizedArrayImpl<T> >
|
||||
{
|
||||
size_t operator()(const Beefy::Array<T>& val) const
|
||||
size_t operator()(const Beefy::SizedArrayImpl<T>& val) const
|
||||
{
|
||||
return _Hash_seq((const uint8*)val.mVals, sizeof(T) * val.mSize);
|
||||
return HashBytes((const uint8*)val.mVals, sizeof(T) * val.mSize);
|
||||
}
|
||||
};
|
||||
}*/
|
||||
|
||||
}
|
||||
|
|
|
@ -993,6 +993,8 @@ bool BfMethodMatcher::WantsCheckMethod(BfProtectionCheckFlags& flags, BfTypeInst
|
|||
|
||||
bool BfMethodMatcher::CheckMethod(BfTypeInstance* typeInstance, BfMethodDef* checkMethod, bool isFailurePass)
|
||||
{
|
||||
BP_ZONE("BfMethodMatcher::CheckMethod");
|
||||
|
||||
bool hadMatch = false;
|
||||
|
||||
// Never consider overrides - they only get found at original method declaration
|
||||
|
@ -2905,7 +2907,9 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfIdentifierNode* identifierNode,
|
|||
return qualifiedResult;
|
||||
}
|
||||
|
||||
return LookupIdentifier(identifierNode, identifierNode->ToString(), ignoreInitialError, hadError);
|
||||
StringT<128> identifierStr;
|
||||
identifierNode->ToString(identifierStr);
|
||||
return LookupIdentifier(identifierNode, identifierStr, ignoreInitialError, hadError);
|
||||
}
|
||||
|
||||
void BfExprEvaluator::Visit(BfIdentifierNode* identifierNode)
|
||||
|
@ -3148,7 +3152,7 @@ BfTypedValue BfExprEvaluator::LookupField(BfAstNode* targetSrc, BfTypedValue tar
|
|||
|
||||
if (resolvedFieldType->IsValuelessType())
|
||||
{
|
||||
return BfTypedValue(mModule->mBfIRBuilder->GetFakeVal(), resolvedFieldType, true);
|
||||
return BfTypedValue(BfIRValue::sValueless, resolvedFieldType, true);
|
||||
}
|
||||
|
||||
if (isConst)
|
||||
|
@ -7286,7 +7290,6 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfQualifiedNameNode* nameNode,
|
|||
{
|
||||
// Lookup left side as a type
|
||||
{
|
||||
SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
|
||||
BfType* type = NULL;
|
||||
{
|
||||
type = mModule->ResolveTypeRef(nameNode->mLeft, NULL, BfPopulateType_Data, BfResolveTypeRefFlag_AllowRef);
|
||||
|
@ -7372,7 +7375,6 @@ void BfExprEvaluator::LookupQualifiedStaticField(BfAstNode* nameNode, BfIdentifi
|
|||
{
|
||||
// Lookup left side as a type
|
||||
{
|
||||
SetAndRestoreValue<bool> prevHadIgnoreError(mModule->mHadIgnoredError, false);
|
||||
BfType* type = NULL;
|
||||
{
|
||||
SetAndRestoreValue<bool> prevIgnoreErrors(mModule->mIgnoreErrors, true);
|
||||
|
@ -8349,6 +8351,7 @@ bool BfExprEvaluator::CanBindDelegate(BfDelegateBindExpression* delegateBindExpr
|
|||
for (int i = 0; i < (int) methodInstance->GetParamCount(); i++)
|
||||
{
|
||||
auto typedValueExpr = &typedValueExprs[i];
|
||||
typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
|
||||
typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
|
||||
typedValueExpr->mRefNode = NULL;
|
||||
args[i] = typedValueExpr;
|
||||
|
@ -8734,6 +8737,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
for (int i = 0; i < (int)methodInstance->GetParamCount(); i++)
|
||||
{
|
||||
auto typedValueExpr = &typedValueExprs[i];
|
||||
typedValueExpr->mTypedValue.mValue = BfIRValue(BfIRValueFlags_Value, -1);
|
||||
typedValueExpr->mTypedValue.mType = methodInstance->GetParamType(i);
|
||||
typedValueExpr->mRefNode = NULL;
|
||||
args[i] = typedValueExpr;
|
||||
|
@ -13160,13 +13164,13 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
if (mayBeSkipCall)
|
||||
resolveArgsFlags = (BfResolveArgFlags)(resolveArgsFlags | BfResolveArgFlag_DeferParamValues);
|
||||
|
||||
// static int sCallIdx = 0;
|
||||
// sCallIdx++;
|
||||
// int callIdx = sCallIdx;
|
||||
// if (callIdx == 1557)
|
||||
// {
|
||||
// NOP;
|
||||
// }
|
||||
static int sCallIdx = 0;
|
||||
sCallIdx++;
|
||||
int callIdx = sCallIdx;
|
||||
if (callIdx == 1557)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
|
||||
BfCheckedKind checkedKind = BfCheckedKind_NotSet;
|
||||
if (attributeState.mCustomAttributes != NULL)
|
||||
|
@ -17208,8 +17212,8 @@ void BfExprEvaluator::PerformBinaryOperation(BfAstNode* leftExpression, BfAstNod
|
|||
|
||||
BfPointerType* resultPointerType = (BfPointerType*)resultType;
|
||||
BfType* intPtrType = mModule->GetPrimitiveType(BfTypeCode_IntPtr);
|
||||
convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, BfCastFlags_Explicit);
|
||||
convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, BfCastFlags_Explicit);
|
||||
convLeftValue = mModule->CastToValue(leftExpression, leftValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
|
||||
convRightValue = mModule->CastToValue(rightExpression, rightValue, intPtrType, (BfCastFlags)(BfCastFlags_Explicit | BfCastFlags_FromCompiler));
|
||||
BfIRValue diffValue = mModule->mBfIRBuilder->CreateSub(convLeftValue, convRightValue);
|
||||
diffValue = mModule->mBfIRBuilder->CreateDiv(diffValue, mModule->GetConstValue(resultPointerType->mElementType->mSize, intPtrType), true);
|
||||
mResult = BfTypedValue(diffValue, intPtrType);
|
||||
|
|
|
@ -215,6 +215,8 @@ static llvm::GlobalValue::LinkageTypes LLVMMapLinkageType(BfIRLinkageType linkag
|
|||
return llvmLinkageType;
|
||||
}
|
||||
|
||||
BfIRValue BfIRValue::sValueless(BfIRValueFlags_Value, -1);
|
||||
|
||||
bool BfIRValue::IsFake() const
|
||||
{
|
||||
return mId < -1;
|
||||
|
@ -1452,6 +1454,98 @@ void BfIRBuilder::WriteSLEB128(int64 value)
|
|||
while (hasMore);
|
||||
}
|
||||
|
||||
void BfIRBuilder::WriteSLEB128(int32 value)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
// if (value >= -0x40)
|
||||
// {
|
||||
// mStream.Write((uint8)value);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (value >= -0x2000)
|
||||
// {
|
||||
// uint16 val =
|
||||
// (((uint16)(value << 1)) & 0x7F00) |
|
||||
// (((uint16)value) & 0x7F) | 0x80;
|
||||
// mStream.Write_2(val);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (value >= -0x100000)
|
||||
// {
|
||||
// uint32 val =
|
||||
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||
// (((uint32)(value << 1)) & 0x7F00) |
|
||||
// (((uint32)value) & 0x7F) | 0x8080;
|
||||
// mStream.Write_3(val);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (value >= -0x8000000)
|
||||
// {
|
||||
// uint32 val =
|
||||
// (((uint32)(value << 3)) & 0x7F000000) |
|
||||
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||
// (((uint32)(value << 1)) & 0x7F00) |
|
||||
// (((uint32)value) & 0x7F) | 0x808080;
|
||||
// mStream.Write_4(val);
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value <= 0x3F)
|
||||
{
|
||||
mStream.Write((uint8)value);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value <= 0x1FFF)
|
||||
{
|
||||
uint16 val =
|
||||
(((uint16)(value << 1)) & 0x7F00) |
|
||||
(((uint16)value) & 0x7F) | 0x80;
|
||||
mStream.Write_2(val);
|
||||
return;
|
||||
}
|
||||
//
|
||||
// if (value <= 0x0FFFFF)
|
||||
// {
|
||||
// uint32 val =
|
||||
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||
// (((uint32)(value << 1)) & 0x7F00) |
|
||||
// (((uint32)value) & 0x7F) | 0x8080;
|
||||
// mStream.Write_3(val);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (value <= 0x7FFFFF)
|
||||
// {
|
||||
// uint32 val =
|
||||
// (((uint32)(value << 3)) & 0x7F000000) |
|
||||
// (((uint32)(value << 2)) & 0x7F0000) |
|
||||
// (((uint32)(value << 1)) & 0x7F00) |
|
||||
// (((uint32)value) & 0x7F) | 0x808080;
|
||||
// mStream.Write_4(val);
|
||||
// return;
|
||||
// }
|
||||
}
|
||||
|
||||
bool hasMore;
|
||||
do
|
||||
{
|
||||
uint8 curByte = (uint8)(value & 0x7f);
|
||||
value >>= 7;
|
||||
hasMore = !((((value == 0) && ((curByte & 0x40) == 0)) ||
|
||||
((value == -1) && ((curByte & 0x40) != 0))));
|
||||
if (hasMore)
|
||||
curByte |= 0x80;
|
||||
mStream.Write(curByte);
|
||||
} while (hasMore);
|
||||
}
|
||||
|
||||
void BfIRBuilder::Write(uint8 val)
|
||||
{
|
||||
mStream.Write(val);
|
||||
|
@ -4550,21 +4644,21 @@ BfIRMDNode BfIRBuilder::DbgCreateImportedModule(BfIRMDNode context, BfIRMDNode n
|
|||
|
||||
BfIRMDNode BfIRBuilder::DbgCreateBasicType(const StringImpl& name, int64 sizeInBits, int64 alignInBits, int encoding)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateBasicType, name, sizeInBits, alignInBits, encoding);
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateBasicType, name, (int32)sizeInBits, (int32)alignInBits, encoding);
|
||||
NEW_CMD_INSERTED_IRMD;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
BfIRMDNode BfIRBuilder::DbgCreateStructType(BfIRMDNode context, const StringImpl& name, BfIRMDNode file, int lineNum, int64 sizeInBits, int64 alignInBits, int flags, BfIRMDNode derivedFrom, const BfSizedArray<BfIRMDNode>& elements)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateStructType, context, name, file, lineNum, sizeInBits, alignInBits, flags, derivedFrom, elements);
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateStructType, context, name, file, lineNum, (int32)sizeInBits, (int32)alignInBits, flags, derivedFrom, elements);
|
||||
NEW_CMD_INSERTED_IRMD;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
BfIRMDNode BfIRBuilder::DbgCreateEnumerationType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, const BfSizedArray<BfIRMDNode>& elements, BfIRMDNode underlyingType)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateEnumerationType, scope, name, file, lineNumber, sizeInBits, alignInBits, elements, underlyingType);
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateEnumerationType, scope, name, file, lineNumber, (int32)sizeInBits, (int32)alignInBits, elements, underlyingType);
|
||||
NEW_CMD_INSERTED_IRMD;
|
||||
return retVal;
|
||||
}
|
||||
|
@ -4606,7 +4700,7 @@ BfIRMDNode BfIRBuilder::DbgCreateArrayType(int64 sizeInBits, int64 alignInBits,
|
|||
|
||||
BfIRMDNode BfIRBuilder::DbgCreateReplaceableCompositeType(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits, int flags)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateReplaceableCompositeType, tag, name, scope, file, line, sizeInBits, alignInBits, flags);
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateReplaceableCompositeType, tag, name, scope, file, line, (int32)sizeInBits, (int32)alignInBits, flags);
|
||||
NEW_CMD_INSERTED_IRMD;
|
||||
return retVal;
|
||||
}
|
||||
|
@ -4627,7 +4721,7 @@ BfIRMDNode BfIRBuilder::DbgCreateForwardDecl(int tag, const StringImpl& name, Bf
|
|||
|
||||
BfIRMDNode BfIRBuilder::DbgCreateSizedForwardDecl(int tag, const StringImpl& name, BfIRMDNode scope, BfIRMDNode file, int line, int64 sizeInBits, int64 alignInBits)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSizedForwardDecl, tag, name, scope, file, line, sizeInBits, alignInBits);
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateSizedForwardDecl, tag, name, scope, file, line, (int32)sizeInBits, (int32)alignInBits);
|
||||
NEW_CMD_INSERTED_IRMD;
|
||||
return retVal;
|
||||
}
|
||||
|
@ -4661,7 +4755,7 @@ BfIRMDNode BfIRBuilder::DbgCreateEnumerator(const StringImpl& name, int64 val)
|
|||
|
||||
BfIRMDNode BfIRBuilder::DbgCreateMemberType(BfIRMDNode scope, const StringImpl& name, BfIRMDNode file, int lineNumber, int64 sizeInBits, int64 alignInBits, int64 offsetInBits, int flags, BfIRMDNode type)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateMemberType, scope, name, file, lineNumber, sizeInBits, alignInBits, offsetInBits, flags, type);
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateMemberType, scope, name, file, lineNumber, (int32)sizeInBits, (int32)alignInBits, (int32)offsetInBits, flags, type);
|
||||
NEW_CMD_INSERTED_IRMD;
|
||||
return retVal;
|
||||
}
|
||||
|
@ -4675,7 +4769,7 @@ BfIRMDNode BfIRBuilder::DbgCreateStaticMemberType(BfIRMDNode scope, const String
|
|||
|
||||
BfIRMDNode BfIRBuilder::DbgCreateInheritance(BfIRMDNode type, BfIRMDNode baseType, int64 baseOffset, int flags)
|
||||
{
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateInheritance, type, baseType, baseOffset, flags);
|
||||
BfIRMDNode retVal = WriteCmd(BfIRCmd_DbgCreateInheritance, type, baseType, (int32)baseOffset, flags);
|
||||
NEW_CMD_INSERTED_IRMD;
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -473,6 +473,7 @@ public:
|
|||
public:
|
||||
int mId;
|
||||
BfIRValueFlags mFlags;
|
||||
static BfIRValue sValueless;
|
||||
|
||||
#ifdef CHECK_CONSTHOLDER
|
||||
BfIRConstHolder* mHolder;
|
||||
|
@ -884,6 +885,7 @@ public:
|
|||
~BfIRBuilder();
|
||||
|
||||
void WriteSLEB128(int64 val);
|
||||
void WriteSLEB128(int32 val);
|
||||
void Write(uint8 val);
|
||||
void Write(bool val);
|
||||
void Write(int val);
|
||||
|
|
|
@ -304,7 +304,7 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name
|
|||
name += "N8delegateI";
|
||||
else
|
||||
name += "N8functionI";
|
||||
BfTypeVector typeVec;
|
||||
SizedArray<BfType*, 8> typeVec;
|
||||
typeVec.push_back(invokeMethodInst->mReturnType);
|
||||
for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
|
||||
{
|
||||
|
@ -1095,7 +1095,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
|||
{
|
||||
auto tupleType = (BfTupleType*)newNameSub.mType;
|
||||
name += "?$__TUPLE";
|
||||
BfTypeVector typeVec;
|
||||
SizedArray<BfType*, 8> typeVec;
|
||||
for (auto& fieldInst : tupleType->mFieldInstances)
|
||||
{
|
||||
BfFieldDef* fieldDef = fieldInst.GetFieldDef();
|
||||
|
@ -1120,7 +1120,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
|||
name += "?$delegate";
|
||||
else
|
||||
name += "?$function";
|
||||
BfTypeVector typeVec;
|
||||
SizedArray<BfType*, 8> typeVec;
|
||||
typeVec.push_back(BfNodeDynCast<BfDirectTypeReference>(methodDef->mReturnTypeRef)->mType);
|
||||
for (int paramIdx = 0; paramIdx < (int)methodDef->mParams.size(); paramIdx++)
|
||||
{
|
||||
|
@ -1139,7 +1139,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
|||
// name += "?$delegate";
|
||||
// else
|
||||
// name += "?$function";
|
||||
// BfTypeVector typeVec;
|
||||
// SizedArray<BfType*, 8> typeVec;
|
||||
// typeVec.push_back(invokeMethodInst->mReturnType);
|
||||
// for (int paramIdx = 0; paramIdx < (int)invokeMethodInst->mParams.size(); paramIdx++)
|
||||
// {
|
||||
|
@ -1156,7 +1156,7 @@ bool BfMSMangler::FindOrCreateNameSub(MangleContext& mangleContext, StringImpl&
|
|||
{
|
||||
auto boxedType = (BfBoxedType*)newNameSub.mTypeInst;
|
||||
name += "?$Box@";
|
||||
BfTypeVector typeVec;
|
||||
SizedArray<BfType*, 8> typeVec;
|
||||
typeVec.push_back(boxedType->GetModifiedElementType());
|
||||
AddGenericArgs(mangleContext, name, typeVec);
|
||||
name += '@';
|
||||
|
|
|
@ -804,7 +804,6 @@ BfModule::BfModule(BfContext* context, const StringImpl& moduleName)
|
|||
mHadBuildWarning = false;
|
||||
mIgnoreErrors = false;
|
||||
mIgnoreWarnings = false;
|
||||
mHadIgnoredError = false;
|
||||
mReportErrors = true;
|
||||
mIsInsideAutoComplete = false;
|
||||
mIsDeleting = false;
|
||||
|
@ -1374,7 +1373,7 @@ BfTypedValue BfModule::GetFakeTypedValue(BfType* type)
|
|||
{
|
||||
// This is a conservative "IsValueless", since it's not an error to use a fakeVal even if we don't need one
|
||||
if (type->mSize == 0)
|
||||
return BfTypedValue(BfIRValue(), type);
|
||||
return BfTypedValue(BfIRValue::sValueless, type);
|
||||
else
|
||||
return BfTypedValue(mBfIRBuilder->GetFakeVal(), type);
|
||||
}
|
||||
|
@ -2447,7 +2446,6 @@ BfError* BfModule::Fail(const StringImpl& error, BfAstNode* refNode, bool isPers
|
|||
|
||||
if (mIgnoreErrors)
|
||||
{
|
||||
mHadIgnoredError = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -8320,6 +8318,9 @@ void BfModule::EmitDynamicCastCheck(const BfTypedValue& targetValue, BfType* tar
|
|||
|
||||
void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool allowNull)
|
||||
{
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
return;
|
||||
|
||||
bool emitDynamicCastCheck = mCompiler->mOptions.mEmitDynamicCastCheck;
|
||||
auto typeOptions = GetTypeOptions();
|
||||
if (typeOptions != NULL)
|
||||
|
@ -8355,6 +8356,12 @@ void BfModule::EmitDynamicCastCheck(BfTypedValue typedVal, BfType* type, bool al
|
|||
|
||||
BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, const BfAllocTarget& allocTarget, bool callDtor)
|
||||
{
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
{
|
||||
if (toType == mContext->mBfObjectType)
|
||||
return BfTypedValue(mBfIRBuilder->GetFakeVal(), toType);
|
||||
}
|
||||
|
||||
BP_ZONE("BoxValue");
|
||||
|
||||
BfTypeInstance* fromStructTypeInstance = typedVal.mType->ToTypeInstance();
|
||||
|
@ -8365,10 +8372,19 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
auto innerType = typedVal.mType->GetUnderlyingType();
|
||||
if (!innerType->IsValueType())
|
||||
{
|
||||
if (!mIgnoreErrors)
|
||||
Fail("Only value types can be boxed", srcNode);
|
||||
return BfTypedValue();
|
||||
}
|
||||
|
||||
auto boxedType = CreateBoxedType(innerType);
|
||||
auto resultType = toType;
|
||||
if (resultType == NULL)
|
||||
resultType = boxedType;
|
||||
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
return BfTypedValue(mBfIRBuilder->GetFakeVal(), resultType);
|
||||
|
||||
auto prevBB = mBfIRBuilder->GetInsertBlock();
|
||||
auto boxBB = mBfIRBuilder->CreateBlock("boxedN.notNull");
|
||||
auto endBB = mBfIRBuilder->CreateBlock("boxedN.end");
|
||||
|
@ -8379,11 +8395,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
|
||||
mBfIRBuilder->CreateCondBr(hasValue, boxBB, endBB);
|
||||
|
||||
auto boxedType = CreateBoxedType(innerType);
|
||||
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
||||
auto resultType = toType;
|
||||
if (resultType == NULL)
|
||||
resultType = boxedType;
|
||||
|
||||
mBfIRBuilder->AddBlock(boxBB);
|
||||
mBfIRBuilder->SetInsertPoint(boxBB);
|
||||
|
@ -8444,15 +8456,14 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
return BfTypedValue();
|
||||
|
||||
// Need to box it
|
||||
auto boxedType = CreateBoxedType(typedVal.mType);
|
||||
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed()) && (boxedType == toType);
|
||||
bool isBoxedType = (fromStructTypeInstance != NULL) && (toType->IsBoxed());
|
||||
|
||||
if ((toType == NULL) || (toType == mContext->mBfObjectType) || (isBoxedType) || (alreadyCheckedCast) || (TypeIsSubTypeOf(fromStructTypeInstance, toTypeInstance)))
|
||||
{
|
||||
if (typedVal.mType->IsPointer())
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
if (mBfIRBuilder->mIgnoreWrites)
|
||||
return BfTypedValue(mBfIRBuilder->GetFakeVal(), (toType != NULL) ? toType : CreateBoxedType(typedVal.mType));
|
||||
|
||||
auto boxedType = CreateBoxedType(typedVal.mType);
|
||||
|
||||
mBfIRBuilder->PopulateType(boxedType);
|
||||
AddDependency(boxedType, mCurTypeInstance, BfDependencyMap::DependencyFlag_ReadFields);
|
||||
|
@ -8463,7 +8474,7 @@ BfTypedValue BfModule::BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
|
||||
if (boxedType->IsUnspecializedType())
|
||||
{
|
||||
BF_ASSERT(mCurMethodInstance->mIsUnspecialized);
|
||||
BF_ASSERT((srcNode == NULL) || (mCurMethodInstance->mIsUnspecialized));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8656,7 +8667,7 @@ int BfModule::GetGenericParamAndReturnCount(BfMethodInstance* methodInstance)
|
|||
return genericCount;
|
||||
}
|
||||
|
||||
BfModule* BfModule::GetSpecializedMethodModule(const Array<BfProject*>& projectList)
|
||||
BfModule* BfModule::GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& projectList)
|
||||
{
|
||||
BF_ASSERT(!mIsScratchModule);
|
||||
BF_ASSERT(mIsReified);
|
||||
|
@ -8667,7 +8678,7 @@ BfModule* BfModule::GetSpecializedMethodModule(const Array<BfProject*>& projectL
|
|||
|
||||
BfModule* specModule = NULL;
|
||||
BfModule** specModulePtr = NULL;
|
||||
if (mainModule->mSpecializedMethodModules.TryGetValue(projectList, &specModulePtr))
|
||||
if (mainModule->mSpecializedMethodModules.TryGetValueWith(projectList, &specModulePtr))
|
||||
{
|
||||
return *specModulePtr;
|
||||
}
|
||||
|
@ -8681,7 +8692,11 @@ BfModule* BfModule::GetSpecializedMethodModule(const Array<BfProject*>& projectL
|
|||
specModule->mParentModule = mainModule;
|
||||
specModule->mIsSpecializedMethodModuleRoot = true;
|
||||
specModule->Init();
|
||||
mainModule->mSpecializedMethodModules[projectList] = specModule;
|
||||
|
||||
Array<BfProject*> projList;
|
||||
for (auto project : projectList)
|
||||
projList.Add(project);
|
||||
mainModule->mSpecializedMethodModules[projList] = specModule;
|
||||
}
|
||||
return specModule;
|
||||
}
|
||||
|
@ -11080,7 +11095,7 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
}
|
||||
|
||||
BfTypeVector sanitizedMethodGenericArguments;
|
||||
Array<BfProject*> projectList;
|
||||
SizedArray<BfProject*, 4> projectList;
|
||||
|
||||
bool isUnspecializedPass = (flags & BfGetMethodInstanceFlag_UnspecializedPass) != 0;
|
||||
if ((isUnspecializedPass) && (methodDef->mGenericParams.size() == 0))
|
||||
|
|
|
@ -833,6 +833,7 @@ public:
|
|||
};
|
||||
|
||||
public:
|
||||
BumpAllocator mBumpAlloc;
|
||||
BfMethodState* mPrevMethodState; // Only non-null for things like local methods
|
||||
BfConstResolveState* mConstResolveState;
|
||||
BfMethodInstance* mMethodInstance;
|
||||
|
@ -841,8 +842,8 @@ public:
|
|||
BfIRBlock mIRHeadBlock;
|
||||
BfIRBlock mIRInitBlock;
|
||||
BfIRBlock mIREntryBlock;
|
||||
Array<BfLocalVariable*> mLocals;
|
||||
HashSet<BfLocalVarEntry> mLocalVarSet;
|
||||
Array<BfLocalVariable*, AllocatorBump<BfLocalVariable*> > mLocals;
|
||||
HashSet<BfLocalVarEntry, AllocatorBump<BfLocalVariable*> > mLocalVarSet;
|
||||
Array<BfLocalMethod*> mLocalMethods;
|
||||
Dictionary<String, BfLocalMethod*> mLocalMethodMap;
|
||||
Dictionary<String, BfLocalMethod*> mLocalMethodCache; // So any lambda 'capturing' and 'processing' stages use the same local method
|
||||
|
@ -900,6 +901,11 @@ public:
|
|||
public:
|
||||
BfMethodState()
|
||||
{
|
||||
mLocals.mAlloc = &mBumpAlloc;
|
||||
mLocals.Reserve(8);
|
||||
mLocalVarSet.mAlloc = &mBumpAlloc;
|
||||
mLocalVarSet.Reserve(8);
|
||||
|
||||
mMethodInstance = NULL;
|
||||
mPrevMethodState = NULL;
|
||||
mConstResolveState = NULL;
|
||||
|
@ -1344,7 +1350,6 @@ public:
|
|||
bool mIgnoreErrors;
|
||||
bool mIgnoreWarnings;
|
||||
bool mSetIllegalSrcPosition;
|
||||
bool mHadIgnoredError;
|
||||
bool mReportErrors; // Still puts system in error state when set to false
|
||||
bool mIsInsideAutoComplete;
|
||||
bool mIsHotModule;
|
||||
|
@ -1439,6 +1444,7 @@ public:
|
|||
BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false);
|
||||
void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry);
|
||||
void EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail);
|
||||
bool DoCanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None);
|
||||
bool CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None);
|
||||
bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting);
|
||||
BfTypedValue BoxValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType /*Can be System.Object or interface*/, const BfAllocTarget& allocTarget, bool callDtor = true);
|
||||
|
@ -1712,7 +1718,7 @@ public:
|
|||
BfMethodInstance* GetRawMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false, bool allowMixin = false);
|
||||
BfMethodInstance* GetUnspecializedMethodInstance(BfMethodInstance* methodInstance); // Unspecialized owner type and unspecialized method type
|
||||
int GetGenericParamAndReturnCount(BfMethodInstance* methodInstance);
|
||||
BfModule* GetSpecializedMethodModule(const Array<BfProject*>& projectList);
|
||||
BfModule* GetSpecializedMethodModule(const SizedArrayImpl<BfProject*>& projectList);
|
||||
BfModuleMethodInstance GetMethodInstanceAtIdx(BfTypeInstance* typeInstance, int methodIdx, const char* assertName = NULL);
|
||||
BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, int paramCount = -1, bool checkBase = false);
|
||||
BfModuleMethodInstance GetMethodByName(BfTypeInstance* typeInstance, const StringImpl& methodName, const Array<BfType*>& paramTypes, bool checkBase = false);
|
||||
|
|
|
@ -4653,8 +4653,6 @@ BfBoxedType* BfModule::CreateBoxedType(BfType* resolvedTypeRef)
|
|||
{
|
||||
bool isStructPtr = false;
|
||||
|
||||
// if (resolvedTypeRef->IsPointer())
|
||||
// resolvedTypeRef = ((BfPointerType*)resolvedTypeRef)->mElementType;
|
||||
if (resolvedTypeRef->IsPrimitiveType())
|
||||
{
|
||||
auto primType = (BfPrimitiveType*)resolvedTypeRef;
|
||||
|
@ -7696,8 +7694,7 @@ BfType* BfModule::ResolveTypeRef(BfAstNode* astNode, const BfSizedArray<BfTypeRe
|
|||
return ResolveTypeRef(typeRef, populateType, resolveFlags);
|
||||
}
|
||||
|
||||
// This flow should mirror CastToValue
|
||||
bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
||||
bool BfModule::DoCanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
||||
{
|
||||
BfType* fromType = typedVal.mType;
|
||||
|
||||
|
@ -7868,8 +7865,8 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
|||
// And from T* to T[size]* explicitly
|
||||
if (fromUnderlying->IsSizedArray())
|
||||
fromUnderlying = fromUnderlying->GetUnderlyingType();
|
||||
// if ((toUnderlying->IsSizedArray()) && (explicitCast))
|
||||
// toUnderlying = toUnderlying->GetUnderlyingType();
|
||||
// if ((toUnderlying->IsSizedArray()) && (explicitCast))
|
||||
// toUnderlying = toUnderlying->GetUnderlyingType();
|
||||
|
||||
if ((fromUnderlying == toUnderlying) ||
|
||||
(TypeIsSubTypeOf(fromUnderlying->ToTypeInstance(), toUnderlying->ToTypeInstance())) ||
|
||||
|
@ -7905,12 +7902,12 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
|||
if (((fromType->IsValueType()) || (fromType->IsPointer()) || (fromType->IsValuelessType())) &&
|
||||
((toType->IsInterface()) || (toType == mContext->mBfObjectType)))
|
||||
{
|
||||
// if (fromType->IsPointer())
|
||||
// {
|
||||
// if (toType == mContext->mBfObjectType)
|
||||
// return true;
|
||||
// return false;
|
||||
// }
|
||||
// if (fromType->IsPointer())
|
||||
// {
|
||||
// if (toType == mContext->mBfObjectType)
|
||||
// return true;
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if (toType == mContext->mBfObjectType)
|
||||
return true;
|
||||
|
@ -7934,7 +7931,71 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
|||
return true;
|
||||
}
|
||||
|
||||
if (fromType->IsRef())
|
||||
// Null -> Nullable<T>
|
||||
if ((typedVal.mType->IsNull()) && (toType->IsNullable()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Nullable<A> -> Nullable<B>
|
||||
if ((typedVal.mType->IsNullable()) && (toType->IsNullable()))
|
||||
{
|
||||
auto fromNullableType = (BfGenericTypeInstance*)typedVal.mType;
|
||||
auto toNullableType = (BfGenericTypeInstance*)toType;
|
||||
|
||||
return CanImplicitlyCast(BfTypedValue(mBfIRBuilder->GetFakeVal(), fromNullableType->mTypeGenericArguments[0]), toNullableType->mTypeGenericArguments[0], castFlags);
|
||||
}
|
||||
|
||||
// Tuple -> Tuple
|
||||
if ((typedVal.mType->IsTuple()) && (toType->IsTuple()))
|
||||
{
|
||||
auto fromTupleType = (BfTupleType*)typedVal.mType;
|
||||
auto toTupleType = (BfTupleType*)toType;
|
||||
if (fromTupleType->mFieldInstances.size() == toTupleType->mFieldInstances.size())
|
||||
{
|
||||
bool canCast = true;
|
||||
|
||||
BfIRValue curTupleValue = mBfIRBuilder->CreateUndefValue(mBfIRBuilder->MapType(toTupleType));
|
||||
for (int valueIdx = 0; valueIdx < (int)fromTupleType->mFieldInstances.size(); valueIdx++)
|
||||
{
|
||||
BfFieldInstance* fromFieldInstance = &fromTupleType->mFieldInstances[valueIdx];
|
||||
BfFieldInstance* toFieldInstance = &toTupleType->mFieldInstances[valueIdx];
|
||||
|
||||
//
|
||||
{
|
||||
BfFieldDef* fromFieldDef = fromFieldInstance->GetFieldDef();
|
||||
BfFieldDef* toFieldDef = toFieldInstance->GetFieldDef();
|
||||
|
||||
// Either the names have to match or one has to be unnamed
|
||||
if ((!fromFieldDef->IsUnnamedTupleField()) && (!toFieldDef->IsUnnamedTupleField()) &&
|
||||
(fromFieldDef->mName != toFieldDef->mName))
|
||||
{
|
||||
curTupleValue = BfIRValue();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
auto fromFieldType = fromFieldInstance->GetResolvedType();
|
||||
auto toFieldType = toFieldInstance->GetResolvedType();
|
||||
|
||||
if (toFieldType->IsVoid())
|
||||
continue; // Allow sinking to void
|
||||
|
||||
BfIRValue fromFieldValue;
|
||||
bool canCastField = CanImplicitlyCast(BfTypedValue(mBfIRBuilder->GetFakeVal(), fromFieldType), toFieldType, (BfCastFlags)(castFlags | BfCastFlags_Explicit));
|
||||
if (!canCastField)
|
||||
{
|
||||
canCast = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (canCast)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*if (fromType->IsRef())
|
||||
{
|
||||
if (toType->IsRef())
|
||||
{
|
||||
|
@ -7946,7 +8007,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
|||
// ref T -> T
|
||||
return fromType->GetUnderlyingType() == toType;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// Int -> Enum
|
||||
if ((typedVal.mType->IsIntegral()) && (toType->IsEnum()))
|
||||
|
@ -8501,7 +8562,7 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
|||
{
|
||||
if ((methodFromType == bestFromType) && (methodToType == bestToType))
|
||||
{
|
||||
return true;
|
||||
return CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, bestToType), toType, castFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8518,9 +8579,56 @@ bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFl
|
|||
}
|
||||
}
|
||||
|
||||
// Prim -> TypedPrimitive
|
||||
if ((typedVal.mType->IsPrimitiveType()) && (toType->IsTypedPrimitive()))
|
||||
{
|
||||
bool allowCast = false;
|
||||
if (toType == mCurTypeInstance)
|
||||
allowCast = true;
|
||||
if ((!allowCast) && (typedVal.mType->IsIntegral()) /*&& (!toType->IsEnum())*/)
|
||||
{
|
||||
// Allow implicit cast of zero
|
||||
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||
if ((constant != NULL) && (mBfIRBuilder->IsInt(constant->mTypeCode)))
|
||||
{
|
||||
allowCast = constant->mInt64 == 0;
|
||||
}
|
||||
}
|
||||
if (allowCast)
|
||||
{
|
||||
return CanImplicitlyCast(typedVal, toType->GetUnderlyingType(), castFlags);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// This flow should mirror CastToValue
|
||||
bool BfModule::CanImplicitlyCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags)
|
||||
{
|
||||
BP_ZONE("BfModule::CanImplicitlyCast");
|
||||
|
||||
//return DoCanImplicitlyCast(typedVal, toType, castFlags);
|
||||
|
||||
bool canCastToValue;
|
||||
{
|
||||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||
canCastToValue = CastToValue(NULL, typedVal, toType, (BfCastFlags)(castFlags | BfCastFlags_SilentFail));
|
||||
return canCastToValue;
|
||||
}
|
||||
|
||||
return canCastToValue;
|
||||
|
||||
bool sideCanCast = DoCanImplicitlyCast(typedVal, toType, castFlags);
|
||||
if (canCastToValue != sideCanCast)
|
||||
{
|
||||
NOP;
|
||||
}
|
||||
//BF_ASSERT(canCastToValue == sideCanCast);
|
||||
return sideCanCast;
|
||||
}
|
||||
|
||||
|
||||
bool BfModule::AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting)
|
||||
{
|
||||
if ((fromType->IsTypeInstance()) && (!fromType->IsSplattable()))
|
||||
|
@ -8600,6 +8708,8 @@ BfIRValue BfModule::CastToFunction(BfAstNode* srcNode, BfMethodInstance* methodI
|
|||
BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags, BfCastResultFlags* resultFlags)
|
||||
{
|
||||
bool explicitCast = (castFlags & BfCastFlags_Explicit) != 0;
|
||||
bool ignoreErrors = mIgnoreErrors || ((castFlags & BfCastFlags_SilentFail) != 0);
|
||||
bool ignoreWrites = mBfIRBuilder->mIgnoreWrites;
|
||||
|
||||
if (typedVal.mType == toType)
|
||||
{
|
||||
|
@ -8693,11 +8803,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
// void* -> intptr
|
||||
if ((typedVal.mType->IsPointer()) && (toType->IsIntPtr()))
|
||||
{
|
||||
//TODO: Put back
|
||||
/*if ((!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
||||
if ((!ignoreErrors) && (!typedVal.mType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
||||
{
|
||||
Fail(StrFormat("Unable to cast direct from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
||||
}*/
|
||||
}
|
||||
|
||||
auto toPrimitive = (BfPrimitiveType*)toType;
|
||||
return mBfIRBuilder->CreatePtrToInt(typedVal.mValue, toPrimitive->mTypeDef->mTypeCode);
|
||||
|
@ -8706,11 +8815,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
// intptr -> void*
|
||||
if ((typedVal.mType->IsIntPtr()) && (toType->IsPointer()))
|
||||
{
|
||||
//TODO: Put back
|
||||
/*if ((!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
||||
if ((!ignoreErrors) && (!toType->GetUnderlyingType()->IsVoid()) && ((castFlags & BfCastFlags_FromCompiler) == 0))
|
||||
{
|
||||
Fail(StrFormat("Unable to cast direct from '%s' to '%s', consider casting to void* first", TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
||||
}*/
|
||||
}
|
||||
|
||||
return mBfIRBuilder->CreateIntToPtr(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
||||
}
|
||||
|
@ -8846,14 +8954,28 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
}
|
||||
}
|
||||
|
||||
if ((typedVal.mType->IsTypeInstance()) && (toType->IsTypeInstance()))
|
||||
{
|
||||
auto fromTypeInstance = typedVal.mType->ToTypeInstance();
|
||||
auto toTypeInstance = toType->ToTypeInstance();
|
||||
|
||||
if ((typedVal.mType->IsValueType()) && (toType->IsValueType()))
|
||||
{
|
||||
bool allowCast = false;
|
||||
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
|
||||
allowCast = true;
|
||||
if (allowCast)
|
||||
{
|
||||
if (toType->IsValuelessType())
|
||||
return BfIRValue::sValueless;
|
||||
}
|
||||
}
|
||||
|
||||
// ObjectInst|IFace -> object|IFace
|
||||
if ((typedVal.mType->IsObject() || (typedVal.mType->IsInterface())) && ((toType->IsObject() || (toType->IsInterface()))))
|
||||
{
|
||||
bool allowCast = false;
|
||||
|
||||
auto fromTypeInstance = typedVal.mType->ToTypeInstance();
|
||||
auto toTypeInstance = toType->ToTypeInstance();
|
||||
|
||||
if (TypeIsSubTypeOf(fromTypeInstance, toTypeInstance))
|
||||
allowCast = true;
|
||||
else if ((explicitCast) &&
|
||||
|
@ -8868,8 +8990,13 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
}
|
||||
|
||||
if (allowCast)
|
||||
{
|
||||
if (ignoreWrites)
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MethodRef -> Function
|
||||
if ((typedVal.mType->IsMethodRef()) && (toType->IsFunction()))
|
||||
|
@ -8918,8 +9045,12 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
allowCast = true;
|
||||
|
||||
if (allowCast)
|
||||
{
|
||||
if (ignoreWrites)
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
return mBfIRBuilder->CreateBitCast(typedVal.mValue, mBfIRBuilder->MapType(toType));
|
||||
}
|
||||
}
|
||||
else if (typedVal.mType->IsObject())
|
||||
{
|
||||
// ???
|
||||
|
@ -8951,9 +9082,10 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
((toType->IsValueType()) || (toType->IsPointer())))
|
||||
{
|
||||
if (toType->IsValuelessType())
|
||||
{
|
||||
return BfIRValue::sValueless;
|
||||
|
||||
if (ignoreWrites)
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
}
|
||||
|
||||
// Unbox!
|
||||
if ((castFlags & BfCastFlags_Unchecked) == 0)
|
||||
|
@ -9036,6 +9168,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
// Null -> Nullable<T>
|
||||
if ((typedVal.mType->IsNull()) && (toType->IsNullable()))
|
||||
{
|
||||
if (ignoreWrites)
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
|
||||
if ((castFlags & BfCastFlags_PreferAddr) != 0)
|
||||
{
|
||||
auto boolType = GetPrimitiveType(BfTypeCode_Boolean);
|
||||
|
@ -9059,6 +9194,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
// Nullable<A> -> Nullable<B>
|
||||
if ((typedVal.mType->IsNullable()) && (toType->IsNullable()))
|
||||
{
|
||||
if (ignoreWrites)
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
|
||||
auto fromNullableType = (BfGenericTypeInstance*)typedVal.mType;
|
||||
auto toNullableType = (BfGenericTypeInstance*)toType;
|
||||
|
||||
|
@ -9073,7 +9211,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
auto srcAddr = mBfIRBuilder->CreateInBoundsGEP(srcPtr, 0, 1); // mValue
|
||||
auto srcVal = mBfIRBuilder->CreateLoad(srcAddr);
|
||||
|
||||
auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mTypeGenericArguments[0]), toNullableType->mTypeGenericArguments[0]);
|
||||
auto toVal = CastToValue(srcNode, BfTypedValue(srcVal, fromNullableType->mTypeGenericArguments[0]), toNullableType->mTypeGenericArguments[0], ignoreErrors ? BfCastFlags_SilentFail : BfCastFlags_None);
|
||||
if (!toVal)
|
||||
return BfIRValue();
|
||||
|
||||
|
@ -9166,7 +9304,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
return typedVal.mValue;
|
||||
}
|
||||
|
||||
if ((castFlags & BfCastFlags_SilentFail) == 0)
|
||||
if (!ignoreErrors)
|
||||
{
|
||||
String valStr;
|
||||
VariantToString(valStr, variantVal);
|
||||
|
@ -9533,7 +9671,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
if (fromDist < 0)
|
||||
{
|
||||
// Allow us to cast a constant int to a smaller type if it satisfies the cast operator
|
||||
if ((typedVal.mValue.IsConst()) && (CanImplicitlyCast(typedVal, methodCheckFromType)))
|
||||
if ((typedVal.mValue.IsConst()) && (CanImplicitlyCast(typedVal, methodCheckFromType, BfCastFlags_NoConversionOperator)))
|
||||
{
|
||||
fromDist = 0;
|
||||
}
|
||||
|
@ -9623,7 +9761,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
{
|
||||
if (mayBeBox)
|
||||
{
|
||||
if (Fail("Ambiguous cast, may be conversion operator or may be boxing request", srcNode) != NULL)
|
||||
if ((!ignoreErrors) && (Fail("Ambiguous cast, may be conversion operator or may be boxing request", srcNode) != NULL))
|
||||
mCompiler->mPassInstance->MoreInfo("See conversion operator", opMethodInstance->mMethodDef->GetRefNode());
|
||||
}
|
||||
|
||||
|
@ -9654,6 +9792,9 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
if (!castedFromValue)
|
||||
return BfIRValue();
|
||||
|
||||
if (ignoreWrites)
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
|
||||
SizedArray<BfIRValue, 1> args;
|
||||
exprEvaluator.PushArg(castedFromValue, args);
|
||||
auto operatorOut = exprEvaluator.CreateCall(moduleMethodInstance.mMethodInstance, mCompiler->IsSkippingExtraResolveChecks() ? BfIRValue() : moduleMethodInstance.mFunc, false, args);
|
||||
|
@ -9675,9 +9816,12 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
|
||||
isAmbiguousCast |= ((bestFromType != NULL) && (bestToType != NULL));
|
||||
if (isAmbiguousCast)
|
||||
{
|
||||
if (!ignoreErrors)
|
||||
{
|
||||
const char* errStr = "Ambiguous conversion operators for casting from '%s' to '%s'";
|
||||
Fail(StrFormat(errStr, TypeToString(typedVal.mType).c_str(), TypeToString(toType).c_str()), srcNode);
|
||||
}
|
||||
return BfIRValue();
|
||||
}
|
||||
|
||||
|
@ -9697,7 +9841,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
{
|
||||
// .. and we can convert the constraint's toType to OUR toType then we're good
|
||||
auto opToVal = genericParam->mExternType;
|
||||
if (CanImplicitlyCast(opToVal, toType))
|
||||
if (CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType))
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
}
|
||||
}
|
||||
|
@ -9722,7 +9866,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
{
|
||||
// .. and we can convert the constraint's toType to OUR toType then we're good
|
||||
auto opToVal = genericParam->mExternType;
|
||||
if (CanImplicitlyCast(opToVal, toType))
|
||||
if (CanImplicitlyCast(BfTypedValue(BfIRValue::sValueless, opToVal), toType))
|
||||
return mBfIRBuilder->GetFakeVal();
|
||||
}
|
||||
}
|
||||
|
@ -9777,7 +9921,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
bool allowCast = explicitCast;
|
||||
if (toType == mCurTypeInstance)
|
||||
allowCast = true;
|
||||
if ((!allowCast) && (typedVal.mType->IsIntegral()) && (!toType->IsEnum()))
|
||||
if ((!allowCast) && (typedVal.mType->IsIntegral()) /*&& (!toType->IsEnum())*/)
|
||||
{
|
||||
// Allow implicit cast of zero
|
||||
auto constant = mBfIRBuilder->GetConstant(typedVal.mValue);
|
||||
|
@ -9803,16 +9947,14 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp
|
|||
Warn(0, "This implicit boxing will only be in scope during the constructor. Consider using a longer-term allocation such as 'box new'", srcNode);
|
||||
}
|
||||
|
||||
SetAndRestoreValue<bool> ignoreWrites(mBfIRBuilder->mIgnoreWrites, ignoreWrites);
|
||||
auto value = BoxValue(srcNode, typedVal, toType, scopeData, (castFlags & BfCastFlags_NoBoxDtor) == 0);
|
||||
if (value)
|
||||
return value.mValue;
|
||||
}
|
||||
|
||||
if ((castFlags & BfCastFlags_SilentFail) == 0)
|
||||
if (!ignoreErrors)
|
||||
{
|
||||
if (mIgnoreErrors)
|
||||
return BfIRValue();
|
||||
|
||||
const char* errStrF = explicitCast ?
|
||||
"Unable to cast '%s' to '%s'" :
|
||||
"Unable to implicitly cast '%s' to '%s'";
|
||||
|
@ -10526,45 +10668,157 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
|||
{
|
||||
BfTypeInstance* typeInstance = (BfTypeInstance*)resolvedType;
|
||||
|
||||
//auto checkTypeInst = typeInstance;
|
||||
//auto checkTypeDef = typeInstance->mTypeDef;
|
||||
|
||||
bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0;
|
||||
if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||
{
|
||||
for (auto& checkNamespace : mCurTypeInstance->mTypeDef->mNamespaceSearch)
|
||||
{
|
||||
if (checkNamespace == typeInstance->mTypeDef->mNamespace)
|
||||
omitNamespace = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!typeInstance->mTypeDef->mNamespace.IsEmpty()) && (!omitNamespace))
|
||||
{
|
||||
if (!typeInstance->mTypeDef->mNamespace.IsEmpty())
|
||||
{
|
||||
typeInstance->mTypeDef->mNamespace.ToString(str);
|
||||
if (!typeInstance->mTypeDef->IsGlobalsContainer())
|
||||
str += '.';
|
||||
}
|
||||
}
|
||||
|
||||
//_AddTypeName(typeInstance->mTypeDef, 0);
|
||||
|
||||
//std::function<void(String& str, BfTypeInstance*, BfTypeDef*, int, BfTypeNameFlags)> _AddTypeName = [&](StringImpl& str, BfTypeInstance*& checkTypeInst, BfTypeDef* checkTypeDef, int depth, BfTypeNameFlags typeNameFlags)
|
||||
|
||||
// BfTypeDef* endTypeDef = NULL;
|
||||
// if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||
// {
|
||||
// auto checkTypeInst = typeInstance;
|
||||
// auto checkTypeDef = typeInstance->mTypeDef;
|
||||
//
|
||||
// auto outerTypeInst = GetOuterType(checkTypeInst);
|
||||
// if (outerTypeInst == NULL)
|
||||
// return;
|
||||
// checkTypeInst = outerTypeInst;
|
||||
//
|
||||
// auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName
|
||||
// BfTypeDef* checkCurTypeDef = NULL;
|
||||
// if (checkCurTypeInst != NULL)
|
||||
// checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||
//
|
||||
// while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
|
||||
// {
|
||||
// checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||
// checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||
// }
|
||||
//
|
||||
// if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
|
||||
// endTypeDef = checkCurTypeDef;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
SizedArray<BfTypeDef*, 8> typeDefStack;
|
||||
|
||||
BfTypeDef* endTypeDef = NULL;
|
||||
if (((typeNameFlags & BfTypeNameFlag_ReduceName) != 0) && (mCurTypeInstance != NULL))
|
||||
{
|
||||
auto checkTypeInst = typeInstance;
|
||||
auto checkTypeDef = typeInstance->mTypeDef;
|
||||
|
||||
auto outerTypeInst = GetOuterType(checkTypeInst);
|
||||
if (outerTypeInst != NULL)
|
||||
{
|
||||
checkTypeInst = outerTypeInst;
|
||||
auto checkTypeDef = checkTypeInst->mTypeDef;
|
||||
|
||||
auto checkCurTypeInst = mCurTypeInstance; // Only used for ReduceName
|
||||
BfTypeDef* checkCurTypeDef = NULL;
|
||||
if (checkCurTypeInst != NULL)
|
||||
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||
|
||||
std::function<void(BfTypeDef*, int)> _AddTypeName = [&](BfTypeDef* checkTypeDef, int depth)
|
||||
{
|
||||
if (depth > 0)
|
||||
{
|
||||
if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
|
||||
return;
|
||||
|
||||
if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||
{
|
||||
auto outerTypeInst = GetOuterType(checkTypeInst);
|
||||
if (outerTypeInst == NULL)
|
||||
return;
|
||||
checkTypeInst = outerTypeInst;
|
||||
|
||||
while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
|
||||
{
|
||||
checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||
}
|
||||
|
||||
while (checkTypeDef != NULL)
|
||||
{
|
||||
if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
|
||||
return; // Found outer type
|
||||
{
|
||||
endTypeDef = checkTypeDef;
|
||||
break;
|
||||
}
|
||||
|
||||
checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||
if (checkCurTypeInst == NULL)
|
||||
break;
|
||||
checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||
|
||||
checkTypeInst = GetOuterType(checkTypeInst);
|
||||
if (checkTypeInst == NULL)
|
||||
break;
|
||||
checkTypeDef = checkTypeInst->mTypeDef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto parentTypeDef = checkTypeDef->mOuterType;
|
||||
if (parentTypeDef != NULL)
|
||||
BfTypeDef* checkTypeDef = typeInstance->mTypeDef;
|
||||
while (checkTypeDef != NULL)
|
||||
{
|
||||
_AddTypeName(parentTypeDef, depth + 1);
|
||||
typeDefStack.Add(checkTypeDef);
|
||||
|
||||
checkTypeDef = checkTypeDef->mOuterType;
|
||||
|
||||
if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
|
||||
break;
|
||||
|
||||
if (checkTypeDef == endTypeDef)
|
||||
break;
|
||||
}
|
||||
|
||||
while (!typeDefStack.IsEmpty())
|
||||
{
|
||||
BfTypeDef* checkTypeDef = typeDefStack.back();
|
||||
int depth = (int)typeDefStack.size() - 1;
|
||||
typeDefStack.pop_back();
|
||||
|
||||
// if (depth > 0)
|
||||
// {
|
||||
// if ((typeNameFlags & BfTypeNameFlag_OmitOuterType) != 0)
|
||||
// return;
|
||||
//
|
||||
// if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||
// {
|
||||
// auto outerTypeInst = GetOuterType(checkTypeInst);
|
||||
// if (outerTypeInst == NULL)
|
||||
// return;
|
||||
// checkTypeInst = outerTypeInst;
|
||||
//
|
||||
// while (checkCurTypeDef->mNestDepth > checkTypeDef->mNestDepth)
|
||||
// {
|
||||
// checkCurTypeInst = GetOuterType(checkCurTypeInst);
|
||||
// checkCurTypeDef = checkCurTypeInst->mTypeDef;
|
||||
// }
|
||||
//
|
||||
// if (TypeIsSubTypeOf(checkCurTypeInst, checkTypeInst))
|
||||
// return; // Found outer type
|
||||
// }
|
||||
// }
|
||||
|
||||
// auto parentTypeDef = checkTypeDef->mOuterType;
|
||||
// if (parentTypeDef != NULL)
|
||||
// {
|
||||
// //_AddTypeName(parentTypeDef, depth + 1);
|
||||
// typeDefStack.Add(parentTypeDef);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if (checkTypeDef->IsGlobalsContainer())
|
||||
{
|
||||
if ((typeNameFlags & BfTypeNameFlag_AddGlobalContainerName) != 0)
|
||||
|
@ -10636,26 +10890,6 @@ void BfModule::DoTypeToString(StringImpl& str, BfType* resolvedType, BfTypeNameF
|
|||
str += '.';
|
||||
};
|
||||
|
||||
bool omitNamespace = (typeNameFlags & BfTypeNameFlag_OmitNamespace) != 0;
|
||||
if ((typeNameFlags & BfTypeNameFlag_ReduceName) != 0)
|
||||
{
|
||||
for (auto& checkNamespace : mCurTypeInstance->mTypeDef->mNamespaceSearch)
|
||||
{
|
||||
if (checkNamespace == typeInstance->mTypeDef->mNamespace)
|
||||
omitNamespace = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!typeInstance->mTypeDef->mNamespace.IsEmpty()) && (!omitNamespace))
|
||||
{
|
||||
if (!typeInstance->mTypeDef->mNamespace.IsEmpty())
|
||||
{
|
||||
typeInstance->mTypeDef->mNamespace.ToString(str);
|
||||
if (!typeInstance->mTypeDef->IsGlobalsContainer())
|
||||
str += '.';
|
||||
}
|
||||
}
|
||||
_AddTypeName(typeInstance->mTypeDef, 0);
|
||||
return;
|
||||
}
|
||||
else if (resolvedType->IsPrimitiveType())
|
||||
|
|
|
@ -3627,64 +3627,6 @@ String BfTypeUtils::HashEncode64(uint64 val)
|
|||
return outStr;
|
||||
}
|
||||
|
||||
void BfTypeUtils::GetProjectList(BfType* checkType, Array<BfProject*>* projectList, int immutableLength)
|
||||
{
|
||||
if (checkType->IsBoxed())
|
||||
GetProjectList(((BfBoxedType*)checkType)->mElementType, projectList, immutableLength);
|
||||
|
||||
BfTypeInstance* typeInst = checkType->ToTypeInstance();
|
||||
if (typeInst != NULL)
|
||||
{
|
||||
auto genericTypeInst = typeInst->ToGenericTypeInstance();
|
||||
if (genericTypeInst != NULL)
|
||||
{
|
||||
for (auto genericArg : genericTypeInst->mTypeGenericArguments)
|
||||
GetProjectList(genericArg, projectList, immutableLength);
|
||||
}
|
||||
|
||||
BfProject* bfProject = typeInst->mTypeDef->mProject;
|
||||
if (std::find(projectList->begin(), projectList->end(), bfProject) == projectList->end())
|
||||
{
|
||||
bool handled = false;
|
||||
for (int idx = 0; idx < (int)projectList->size(); idx++)
|
||||
{
|
||||
auto checkProject = (*projectList)[idx];
|
||||
bool isBetter = bfProject->ContainsReference(checkProject);
|
||||
bool isWorse = checkProject->ContainsReference(bfProject);
|
||||
if (isBetter == isWorse)
|
||||
continue;
|
||||
if (isBetter)
|
||||
{
|
||||
if (idx >= immutableLength)
|
||||
{
|
||||
// This is even more specific, so replace with this one
|
||||
(*projectList)[idx] = bfProject;
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is less specific, ignore
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!handled)
|
||||
{
|
||||
projectList->push_back(bfProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (checkType->IsPointer())
|
||||
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
||||
else if (checkType->IsRef())
|
||||
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
||||
else if (checkType->IsSizedArray())
|
||||
GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength);
|
||||
else if (checkType->IsMethodRef())
|
||||
GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength);
|
||||
}
|
||||
|
||||
BfPrimitiveType* BfTypeUtils::GetPrimitiveType(BfModule* module, BfTypeCode typeCode)
|
||||
{
|
||||
return module->GetPrimitiveType(typeCode);
|
||||
|
|
|
@ -2332,7 +2332,64 @@ public:
|
|||
static bool TypeToString(StringImpl& str, BfTypeDef* typeDef, BfTypeNameFlags typeNameFlags = BfTypeNameFlags_None);
|
||||
static bool TypeEquals(BfType* typeA, BfType* typeB, BfType* selfType);
|
||||
|
||||
static void GetProjectList(BfType* checkType, Array<BfProject*>* projectVector, int immutableLength);
|
||||
template <typename T>
|
||||
static void GetProjectList(BfType* checkType, T* projectList, int immutableLength)
|
||||
{
|
||||
if (checkType->IsBoxed())
|
||||
GetProjectList(((BfBoxedType*)checkType)->mElementType, projectList, immutableLength);
|
||||
|
||||
BfTypeInstance* typeInst = checkType->ToTypeInstance();
|
||||
if (typeInst != NULL)
|
||||
{
|
||||
auto genericTypeInst = typeInst->ToGenericTypeInstance();
|
||||
if (genericTypeInst != NULL)
|
||||
{
|
||||
for (auto genericArg : genericTypeInst->mTypeGenericArguments)
|
||||
GetProjectList(genericArg, projectList, immutableLength);
|
||||
}
|
||||
|
||||
BfProject* bfProject = typeInst->mTypeDef->mProject;
|
||||
if (!projectList->Contains(bfProject))
|
||||
{
|
||||
bool handled = false;
|
||||
for (int idx = 0; idx < (int)projectList->size(); idx++)
|
||||
{
|
||||
auto checkProject = (*projectList)[idx];
|
||||
bool isBetter = bfProject->ContainsReference(checkProject);
|
||||
bool isWorse = checkProject->ContainsReference(bfProject);
|
||||
if (isBetter == isWorse)
|
||||
continue;
|
||||
if (isBetter)
|
||||
{
|
||||
if (idx >= immutableLength)
|
||||
{
|
||||
// This is even more specific, so replace with this one
|
||||
(*projectList)[idx] = bfProject;
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is less specific, ignore
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!handled)
|
||||
{
|
||||
projectList->Add(bfProject);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (checkType->IsPointer())
|
||||
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
||||
else if (checkType->IsRef())
|
||||
GetProjectList(((BfPointerType*)checkType)->mElementType, projectList, immutableLength);
|
||||
else if (checkType->IsSizedArray())
|
||||
GetProjectList(((BfSizedArrayType*)checkType)->mElementType, projectList, immutableLength);
|
||||
else if (checkType->IsMethodRef())
|
||||
GetProjectList(((BfMethodRefType*)checkType)->mOwner, projectList, immutableLength);
|
||||
}
|
||||
|
||||
static BfPrimitiveType* GetPrimitiveType(BfModule* module, BfTypeCode typeCode);
|
||||
static void PopulateType(BfModule* module, BfType* type);
|
||||
|
|
|
@ -1162,7 +1162,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
|||
BfLocalVariable* localDef = new BfLocalVariable();
|
||||
if (varDecl->mNameNode != NULL)
|
||||
{
|
||||
localDef->mName = varDecl->mNameNode->ToString();
|
||||
varDecl->mNameNode->ToString(localDef->mName);
|
||||
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varDecl->mNameNode);
|
||||
}
|
||||
else
|
||||
|
@ -1773,7 +1773,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD
|
|||
|
||||
BfLocalVariable* localDef = new BfLocalVariable();
|
||||
if (varDecl->mNameNode != NULL)
|
||||
localDef->mName = varDecl->mNameNode->ToString();
|
||||
varDecl->mNameNode->ToString(localDef->mName);
|
||||
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varDecl->mNameNode);
|
||||
localDef->mResolvedType = type;
|
||||
localDef->mIsAssigned = true;
|
||||
|
@ -1906,7 +1906,7 @@ void BfModule::HandleTupleVariableDeclaration(BfVariableDeclaration* varDecl, Bf
|
|||
bool initHandled = false;
|
||||
|
||||
BfLocalVariable* localDef = new BfLocalVariable();
|
||||
localDef->mName = varNameNode->ToString();
|
||||
varNameNode->ToString(localDef->mName);
|
||||
localDef->mNameNode = BfNodeDynCast<BfIdentifierNode>(varNameNode);
|
||||
localDef->mResolvedType = resolvedType;
|
||||
localDef->mReadFromId = 0; // Don't give usage errors for binds
|
||||
|
@ -2326,9 +2326,9 @@ BfTypedValue BfModule::TryCaseEnumMatch(BfTypedValue enumVal, BfTypedValue tagVa
|
|||
auto enumType = targetType->ToTypeInstance();
|
||||
PopulateType(enumType);
|
||||
|
||||
String enumCaseName;
|
||||
StringT<128> enumCaseName;
|
||||
if (nameNode != NULL)
|
||||
enumCaseName = nameNode->ToString();
|
||||
nameNode->ToString(enumCaseName);
|
||||
|
||||
auto tagType = GetPrimitiveType(BfTypeCode_Int32);
|
||||
if (enumVal.mType != enumType)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
|
@ -218,7 +218,7 @@
|
|||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>BP_DISABLED;WIN32;NDEBUG;_WINDOWS;_USRDLL;IDEHELPER_EXPORTS;BFSYSLIB_DYNAMIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>../;../BeefySysLib/platform/win;../BeefySysLib/third_party;..\extern\llvm-project_8_0_1\llvm\include;..\extern\llvm_win64_8_0_1\include;..\extern\llvm-project_8_0_1\llvm\lib\Target;..\extern\llvm_win64_8_0_1\lib\Target\X86;..\extern\llvm-project_8_0_1\llvm\tools\clang\include;..\extern\curl\builds\libcurl-vc15-x64-release-static-zlib-static-ipv6-sspi-winssl\include</AdditionalIncludeDirectories>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue