mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-09 03:52:19 +02:00
Added ZeroGap to AllowAppend
This commit is contained in:
parent
ce42dc4fbe
commit
161d9dc540
19 changed files with 334 additions and 88 deletions
|
@ -372,7 +372,7 @@ namespace System
|
|||
[AttributeUsage(.Constructor)]
|
||||
public struct AllowAppendAttribute : Attribute
|
||||
{
|
||||
|
||||
public bool ZeroGap;
|
||||
}
|
||||
|
||||
[AttributeUsage(.Class | .Struct)]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Collections;
|
||||
|
||||
namespace System
|
||||
{
|
||||
|
@ -105,6 +106,8 @@ namespace System
|
|||
{
|
||||
String emitStr = scope .();
|
||||
|
||||
HashSet<String> foundSigs = scope .();
|
||||
|
||||
for (var methodInfo in typeof(T).GetMethods(.Public | .DeclaredOnly))
|
||||
{
|
||||
if (methodInfo.IsStatic)
|
||||
|
@ -112,11 +115,15 @@ namespace System
|
|||
if (!methodInfo.IsConstructor)
|
||||
continue;
|
||||
|
||||
var sig = methodInfo.GetMethodSig(.. new .());
|
||||
if (!foundSigs.Add(sig))
|
||||
continue;
|
||||
|
||||
emitStr.AppendF("public static RefCounted<T> Create(");
|
||||
methodInfo.GetParamsDecl(emitStr);
|
||||
emitStr.AppendF(")\n");
|
||||
emitStr.AppendF("{{\n");
|
||||
emitStr.AppendF("\treturn new [Friend] RefCountedAppend<T>(");
|
||||
emitStr.AppendF("\treturn new [Friend]RefCountedAppend<T>(");
|
||||
methodInfo.GetArgsList(emitStr);
|
||||
emitStr.AppendF(");\n}}\n");
|
||||
}
|
||||
|
@ -207,7 +214,16 @@ namespace System
|
|||
if (!methodInfo.IsConstructor)
|
||||
continue;
|
||||
|
||||
emitStr.AppendF("[AllowAppend]\nprotected this(");
|
||||
if (methodInfo.AllowAppendKind == .Yes)
|
||||
emitStr.AppendF("[AllowAppend]\n");
|
||||
if (methodInfo.AllowAppendKind == .ZeroGap)
|
||||
emitStr.AppendF("[AllowAppend(ZeroGap=true)]\n");
|
||||
if (methodInfo.CheckedKind == .Checked)
|
||||
emitStr.AppendF("[Checked]\n");
|
||||
if (methodInfo.CheckedKind == .Unchecked)
|
||||
emitStr.AppendF("[Unchecked]\n");
|
||||
|
||||
emitStr.AppendF("protected this(");
|
||||
methodInfo.GetParamsDecl(emitStr);
|
||||
emitStr.AppendF(")\n");
|
||||
emitStr.AppendF("{{\n");
|
||||
|
|
|
@ -530,11 +530,8 @@ namespace System.Reflection
|
|||
}
|
||||
}
|
||||
|
||||
public Result<T*> GetValueReference<T>(Object target)
|
||||
Result<T*> DoGetValueReference<T>(Object target)
|
||||
{
|
||||
if (FieldType != typeof(T))
|
||||
return .Err;
|
||||
|
||||
void* targetDataAddr;
|
||||
if (target == null)
|
||||
{
|
||||
|
@ -556,6 +553,21 @@ namespace System.Reflection
|
|||
}
|
||||
}
|
||||
|
||||
public Result<T*> GetValueReference<T>(Object target)
|
||||
{
|
||||
if (FieldType != typeof(T))
|
||||
return .Err;
|
||||
return DoGetValueReference<T>(target);
|
||||
}
|
||||
|
||||
public Result<T> GetValue<T>(Object target)
|
||||
{
|
||||
if ((FieldType != typeof(T)) && (!FieldType.IsSubtypeOf(typeof(T))))
|
||||
return .Err;
|
||||
T* result = Try!(DoGetValueReference<T>(target));
|
||||
return *result;
|
||||
}
|
||||
|
||||
public Result<Variant> GetValueReference(Object target)
|
||||
{
|
||||
void* targetDataAddr;
|
||||
|
|
|
@ -82,6 +82,13 @@ namespace System.Reflection
|
|||
Name == "~this" :
|
||||
mData.mMethodData.mName === "~this";
|
||||
|
||||
public AllowAppendKind AllowAppendKind => Compiler.IsComptime ?
|
||||
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.AllowAppendKind :
|
||||
mData.mMethodData.[Friend]mFlags.AllowAppendKind;
|
||||
public CheckedKind CheckedKind => Compiler.IsComptime ?
|
||||
Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mMethodFlags.CheckedKind :
|
||||
mData.mMethodData.[Friend]mFlags.CheckedKind;
|
||||
|
||||
public Type ReturnType => Compiler.IsComptime ?
|
||||
Type.[Friend]GetType((.)Type.[Friend]Comptime_Method_GetInfo(mData.mComptimeMethodInstance).mReturnTypeId) :
|
||||
Type.[Friend]GetType(mData.mMethodData.mReturnType);
|
||||
|
|
|
@ -74,13 +74,33 @@ namespace System
|
|||
const uint32 cStrPtrFlag = 0x40000000;
|
||||
#endif
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(int count) // 0
|
||||
{
|
||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
Init(bufferSize);
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
public this(int count) // 0
|
||||
{
|
||||
int bufferSize = count;
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
mPtrOrBuffer = addlPtr;
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize | cStrPtrFlag;
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this()
|
||||
{
|
||||
let bufferSize = 16 - sizeof(char8*);
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||
mLength = 0;
|
||||
}
|
||||
|
@ -88,28 +108,52 @@ namespace System
|
|||
[AllowAppend]
|
||||
public this()
|
||||
{
|
||||
let bufferSize = 16 - sizeof(char8*);
|
||||
let bufferSize = 8;
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
Init(bufferSize);
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||
mPtrOrBuffer = addlPtr;
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize | cStrPtrFlag;
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(String str)
|
||||
{
|
||||
let count = str.mLength;
|
||||
/*int a = __appendIdx;
|
||||
int b = offsetof(String, mPtrOrBuffer);
|
||||
if (__appendIdx == offsetof(String, mPtrOrBuffer))
|
||||
{
|
||||
|
||||
}*/
|
||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
Init(bufferSize);
|
||||
Internal.MemCpy(Ptr, str.Ptr, count);
|
||||
mLength = count;
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
public this(String str)
|
||||
{
|
||||
let count = str.mLength;
|
||||
/*int a = __appendIdx;
|
||||
int b = offsetof(String, mPtrOrBuffer);
|
||||
if (__appendIdx == offsetof(String, mPtrOrBuffer))
|
||||
{
|
||||
|
||||
}*/
|
||||
int bufferSize = count;
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
mPtrOrBuffer = addlPtr;
|
||||
Internal.MemCpy(Ptr, str.Ptr, count);
|
||||
mLength = count;
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize | cStrPtrFlag;
|
||||
}
|
||||
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(String str, int offset)
|
||||
{
|
||||
Debug.Assert((uint)offset <= (uint)str.Length);
|
||||
|
@ -126,7 +170,7 @@ namespace System
|
|||
mLength = (int_strsize)count;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(String str, int offset, int count)
|
||||
{
|
||||
Debug.Assert((uint)offset <= (uint)str.Length);
|
||||
|
@ -144,7 +188,7 @@ namespace System
|
|||
mLength = (int_strsize)count;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(char8 c, int count)
|
||||
{
|
||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||
|
@ -158,7 +202,7 @@ namespace System
|
|||
mLength = (int_strsize)count;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(char8* char8Ptr)
|
||||
{
|
||||
let count = Internal.CStrLen(char8Ptr);
|
||||
|
@ -173,7 +217,7 @@ namespace System
|
|||
mLength = count;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(char8* char8Ptr, int count)
|
||||
{
|
||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||
|
@ -187,7 +231,7 @@ namespace System
|
|||
mLength = (int_strsize)count;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(char16* char16Ptr)
|
||||
{
|
||||
let count = UTF16.GetLengthAsUTF8(char16Ptr);
|
||||
|
@ -200,7 +244,7 @@ namespace System
|
|||
UTF16.Decode(char16Ptr, this);
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(Span<char16> chars)
|
||||
{
|
||||
let count = UTF16.GetLengthAsUTF8(chars);
|
||||
|
@ -213,14 +257,13 @@ namespace System
|
|||
UTF16.Decode(chars, this);
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(StringView strView)
|
||||
{
|
||||
let count = strView.Length;
|
||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
Init(bufferSize);
|
||||
let ptr = Ptr;
|
||||
Internal.MemCpy(ptr, strView.Ptr, strView.Length);
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize + (int_strsize)sizeof(char8*);
|
||||
|
@ -228,6 +271,20 @@ namespace System
|
|||
}
|
||||
|
||||
[AllowAppend]
|
||||
public this(StringView strView)
|
||||
{
|
||||
let count = strView.Length;
|
||||
int bufferSize = count;
|
||||
#unwarn
|
||||
char8* addlPtr = append char8[bufferSize]*(?);
|
||||
mPtrOrBuffer = addlPtr;
|
||||
let ptr = Ptr;
|
||||
Internal.MemCpy(ptr, strView.Ptr, strView.Length);
|
||||
mAllocSizeAndFlags = (uint_strsize)bufferSize | cStrPtrFlag;
|
||||
mLength = (int_strsize)strView.Length;
|
||||
}
|
||||
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(StringView strView, CreateFlags flags)
|
||||
{
|
||||
let count = strView.Length + (flags.HasFlag(.NullTerminate) ? 1 : 0);
|
||||
|
@ -243,7 +300,7 @@ namespace System
|
|||
mLength = (int32)strView.Length;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(StringView strView, int offset)
|
||||
{
|
||||
Debug.Assert((uint)offset <= (uint)strView.Length);
|
||||
|
@ -261,7 +318,7 @@ namespace System
|
|||
mLength = (int_strsize)count;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(StringView strView, int offset, int count)
|
||||
{
|
||||
Debug.Assert((uint)offset <= (uint)strView.Length);
|
||||
|
@ -279,7 +336,7 @@ namespace System
|
|||
mLength = (int_strsize)count;
|
||||
}
|
||||
|
||||
[AllowAppend]
|
||||
[AllowAppend(ZeroGap=true)]
|
||||
public this(char8[] chars, int offset, int count)
|
||||
{
|
||||
int bufferSize = (count == 0) ? 0 : (count - 1) & ~(sizeof(char8*) - 1);
|
||||
|
@ -670,7 +727,7 @@ namespace System
|
|||
public static implicit operator Span<char8>(String str)
|
||||
{
|
||||
if (str == null)
|
||||
return .(null, 0);
|
||||
return .((char8*)null, 0);
|
||||
return .(str.Ptr, str.Length);
|
||||
}
|
||||
|
||||
|
|
|
@ -1742,9 +1742,9 @@ namespace System.Reflection
|
|||
Appended = 0x1000,
|
||||
}
|
||||
|
||||
public enum MethodFlags : uint16
|
||||
public enum MethodFlags : uint32
|
||||
{
|
||||
MethodAccessMask = 0x0007,
|
||||
case MethodAccessMask = 0x0007,
|
||||
Protected = 0x0003,
|
||||
Public = 0x0006,
|
||||
|
||||
|
@ -1762,5 +1762,26 @@ namespace System.Reflection
|
|||
ThisCall = 0x3000, // Purposely resuing StdCall|FastCall
|
||||
Mutating = 0x4000,
|
||||
Constructor = 0x8000,
|
||||
AppendBit0 = 0x10000,
|
||||
AppendBit1 = 0x20000,
|
||||
CheckedBit0 = 0x40000,
|
||||
CheckedBit1 = 0x80000;
|
||||
|
||||
public AllowAppendKind AllowAppendKind => (.)(int32)(this / AppendBit0);
|
||||
public CheckedKind CheckedKind => (.)(int32)(this / CheckedBit0);
|
||||
}
|
||||
|
||||
public enum AllowAppendKind
|
||||
{
|
||||
No,
|
||||
Yes,
|
||||
ZeroGap
|
||||
}
|
||||
|
||||
public enum CheckedKind
|
||||
{
|
||||
NotSet,
|
||||
Checked,
|
||||
Unchecked
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1347,7 +1347,7 @@ namespace System.Reflection
|
|||
EnumCase = 0x0400
|
||||
}
|
||||
|
||||
public enum MethodFlags : uint16
|
||||
public enum MethodFlags : uint32
|
||||
{
|
||||
MethodAccessMask = 0x0007,
|
||||
PrivateScope = 0x0000, // Member not referenceable.
|
||||
|
@ -1382,5 +1382,9 @@ namespace System.Reflection
|
|||
ThisCall = 0x3000, // Purposely resuing StdCall|FastCall
|
||||
Mutating = 0x4000,
|
||||
Constructor = 0x8000,
|
||||
AppendBit0 = 0x10000,
|
||||
AppendBit1 = 0x20000,
|
||||
CheckedBit0 = 0x40000,
|
||||
CheckedBit1 = 0x80000
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1817,7 +1817,7 @@ namespace IDE.ui
|
|||
|
||||
if (!fts_fuzzy_match(filter.CStr(), entry.mEntryDisplay.CStr(), ref score, &matches, matches.Count))
|
||||
{
|
||||
entry.SetMatches(Span<uint8>(null, 0));
|
||||
entry.SetMatches(Span<uint8>((uint8*)null, 0));
|
||||
entry.mScore = score;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2906,7 +2906,10 @@ namespace IDE.ui
|
|||
|
||||
base.UpdateAll();
|
||||
if (mWantRemoveSelf)
|
||||
{
|
||||
mParentItem?.RemoveChildItem(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mColumnIdx == 0)
|
||||
{
|
||||
|
|
|
@ -2520,7 +2520,7 @@ bool BfAutoComplete::GetMethodInfo(BfMethodInstance* methodInst, StringImpl* sho
|
|||
|
||||
auto methodDeclaration = methodDef->GetMethodDeclaration();
|
||||
|
||||
if (methodDef->mHasAppend)
|
||||
if (methodDef->HasAppend())
|
||||
methodPrefix += "[AllowAppend]\r";
|
||||
|
||||
if (isInterface)
|
||||
|
@ -4083,7 +4083,7 @@ void BfAutoComplete::FixitAddConstructor(BfTypeInstance *typeInstance)
|
|||
|
||||
int insertPos = FixitGetMemberInsertPos(mModule->mCurTypeInstance->mTypeDef);
|
||||
String methodStr = "\f\a";
|
||||
if (methodInstance->mMethodDef->mHasAppend)
|
||||
if (methodInstance->mMethodDef->HasAppend())
|
||||
methodStr += "[AllowAppend]\r";
|
||||
methodStr += "public this(";
|
||||
int useParamIdx = 0;
|
||||
|
|
|
@ -829,8 +829,24 @@ void BfDefBuilder::ParseAttributes(BfAttributeDirective* attributes, BfMethodDef
|
|||
}
|
||||
else if (typeRefName == "AllowAppend")
|
||||
{
|
||||
methodDef->mHasAppend = true;
|
||||
methodDef->mAppendKind = BfAllowAppendKind_Yes;
|
||||
methodDef->mIsNoSplat = true;
|
||||
if (!attributes->mArguments.IsEmpty())
|
||||
{
|
||||
if (auto assignExpr = BfNodeDynCast<BfAssignmentExpression>(attributes->mArguments[0]))
|
||||
{
|
||||
if ((assignExpr->mLeft != NULL) && (assignExpr->mRight != NULL) &&
|
||||
(assignExpr->mLeft->Equals("ZeroGap")))
|
||||
{
|
||||
if (assignExpr->mRight->Equals("true"))
|
||||
methodDef->mAppendKind = BfAllowAppendKind_ZeroGap;
|
||||
else if (assignExpr->mRight->Equals("false"))
|
||||
methodDef->mAppendKind = BfAllowAppendKind_Yes;
|
||||
else
|
||||
Fail("Can only use 'true' or 'false' for 'ZeroGap'", assignExpr->mRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (typeRefName == "Checked")
|
||||
methodDef->mCheckedKind = BfCheckedKind_Checked;
|
||||
|
@ -2090,7 +2106,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
hasDefaultCtor = true;
|
||||
|
||||
auto ctorDeclaration = (BfConstructorDeclaration*)method->mMethodDeclaration;
|
||||
if (method->mHasAppend)
|
||||
if (method->mAppendKind != BfAllowAppendKind_No)
|
||||
{
|
||||
mCurTypeDef->mHasAppendCtor = true;
|
||||
|
||||
|
@ -2105,6 +2121,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
methodDef->mProtection = BfProtection_Public;
|
||||
methodDef->mMethodType = BfMethodType_CtorCalcAppend;
|
||||
methodDef->mIsMutating = method->mIsMutating;
|
||||
methodDef->mAppendKind = method->mAppendKind;
|
||||
methodDef->mIsNoSplat = true;
|
||||
|
||||
methodDef->mMethodDeclaration = method->mMethodDeclaration;
|
||||
|
@ -2133,7 +2150,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
|
||||
// Insert a 'appendIdx'
|
||||
BfParameterDef* newParam = new BfParameterDef();
|
||||
newParam->mName = "appendIdx";
|
||||
newParam->mName = "__appendIdx";
|
||||
newParam->mTypeRef = mSystem->mDirectRefIntTypeRef;
|
||||
newParam->mParamKind = BfParamKind_AppendIdx;
|
||||
method->mParams.Insert(0, newParam);
|
||||
|
@ -2524,7 +2541,7 @@ void BfDefBuilder::FinishTypeDef(bool wantsToString)
|
|||
mSignatureHashCtx->MixinStr(methodDef->mName);
|
||||
|
||||
if ((methodDef->mAlwaysInline) ||
|
||||
(methodDef->mHasAppend) ||
|
||||
(methodDef->mAppendKind != BfAllowAppendKind_No) ||
|
||||
(methodDef->mMethodType == BfMethodType_Mixin))
|
||||
inlineHashCtx.Mixin(methodDef->mFullHash);
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ void BfMethodMatcher::Init(const BfMethodGenericArguments& methodGenericArgument
|
|||
mAutoFlushAmbiguityErrors = true;
|
||||
mMethodCheckCount = 0;
|
||||
mCheckedKind = BfCheckedKind_NotSet;
|
||||
mAllowAppendKind = BfAllowAppendKind_No;
|
||||
mMatchFailKind = MatchFailKind_None;
|
||||
mBfEvalExprFlags = BfEvalExprFlags_None;
|
||||
|
||||
|
@ -808,7 +809,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
|||
bool anyIsExtension = false;
|
||||
|
||||
int newImplicitParamCount = newMethodInstance->GetImplicitParamCount();
|
||||
if (newMethodInstance->mMethodDef->mHasAppend)
|
||||
if (newMethodInstance->mMethodDef->HasAppend())
|
||||
newImplicitParamCount++;
|
||||
if (newMethodInstance->mMethodDef->mMethodType == BfMethodType_Extension)
|
||||
{
|
||||
|
@ -817,7 +818,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
|||
}
|
||||
|
||||
int prevImplicitParamCount = prevMethodInstance->GetImplicitParamCount();
|
||||
if (prevMethodInstance->mMethodDef->mHasAppend)
|
||||
if (prevMethodInstance->mMethodDef->HasAppend())
|
||||
prevImplicitParamCount++;
|
||||
if (prevMethodInstance->mMethodDef->mMethodType == BfMethodType_Extension)
|
||||
{
|
||||
|
@ -1281,6 +1282,7 @@ void BfMethodMatcher::CompareMethods(BfMethodInstance* prevMethodInstance, BfTyp
|
|||
}
|
||||
|
||||
RETURN_BETTER_OR_WORSE(newMethodDef->mCheckedKind == mCheckedKind, prevMethodDef->mCheckedKind == mCheckedKind);
|
||||
RETURN_BETTER_OR_WORSE(newMethodDef->mAppendKind == mAllowAppendKind, prevMethodDef->mAppendKind == mAllowAppendKind);
|
||||
RETURN_BETTER_OR_WORSE(newMethodDef->mCommutableKind != BfCommutableKind_Reverse, prevMethodDef->mCommutableKind != BfCommutableKind_Reverse);
|
||||
|
||||
// If one of these methods is local to the current extension then choose that one
|
||||
|
@ -1775,7 +1777,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
|||
((!mHadExplicitGenericArguments) || (mHadPartialGenericArguments));
|
||||
int paramIdx = 0;
|
||||
BfType* paramsElementType = NULL;
|
||||
if (checkMethod->mHasAppend)
|
||||
if (checkMethod->HasAppend())
|
||||
paramIdx++;
|
||||
|
||||
int uniqueGenericStartIdx = mModule->GetLocalInferrableGenericArgCount(checkMethod);
|
||||
|
@ -1887,7 +1889,7 @@ bool BfMethodMatcher::CheckMethod(BfTypeInstance* targetTypeInstance, BfTypeInst
|
|||
int argIdx = 0;
|
||||
int paramIdx = 0;
|
||||
|
||||
if (checkMethod->mHasAppend)
|
||||
if (checkMethod->HasAppend())
|
||||
paramIdx++;
|
||||
|
||||
if (checkMethod->mMethodType == BfMethodType_Extension)
|
||||
|
@ -2636,7 +2638,7 @@ Done:
|
|||
return mBestMethodDef == checkMethod;
|
||||
}
|
||||
|
||||
void BfMethodMatcher::FlushAmbiguityError()
|
||||
void BfMethodMatcher::FlushAmbiguityError(bool useWarning)
|
||||
{
|
||||
if (!mAmbiguousEntries.empty())
|
||||
{
|
||||
|
@ -2644,9 +2646,20 @@ void BfMethodMatcher::FlushAmbiguityError()
|
|||
{
|
||||
BfError* error;
|
||||
if (!mMethodName.empty())
|
||||
{
|
||||
if (useWarning)
|
||||
error = mModule->Warn(0, StrFormat("Ambiguous method call for '%s'", mMethodName.c_str()), mTargetSrc);
|
||||
else
|
||||
error = mModule->Fail(StrFormat("Ambiguous method call for '%s'", mMethodName.c_str()), mTargetSrc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (useWarning)
|
||||
error = mModule->Warn(0, "Ambiguous method call", mTargetSrc);
|
||||
else
|
||||
error = mModule->Fail("Ambiguous method call", mTargetSrc);
|
||||
}
|
||||
|
||||
if (error != NULL)
|
||||
{
|
||||
BfMethodInstance* bestMethodInstance = mModule->GetUnspecializedMethodInstance(mBestRawMethodInstance, true);
|
||||
|
@ -8037,7 +8050,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
arrayType, false);
|
||||
|
||||
BfResolvedArgs resolvedArgs;
|
||||
MatchConstructor(targetSrc, NULL, expandedParamsArray, arrayType, resolvedArgs, false, BfMethodGenericArguments(), false);
|
||||
MatchConstructor(targetSrc, NULL, expandedParamsArray, arrayType, resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
|
||||
|
||||
//TODO: Assert 'length' var is at slot 1
|
||||
auto arrayBits = mModule->mBfIRBuilder->CreateBitCast(expandedParamsArray.mValue, mModule->mBfIRBuilder->MapType(arrayType->mBaseType));
|
||||
|
@ -8806,15 +8819,21 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValu
|
|||
}
|
||||
|
||||
BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType, BfResolvedArgs& argValues, bool callCtorBodyOnly,
|
||||
const BfMethodGenericArguments& methodGenericArguments, bool allowAppendAlloc, BfTypedValue* appendIndexValue)
|
||||
const BfMethodGenericArguments& methodGenericArguments, BfAllowAppendKind allowAppendKind, BfTypedValue* appendIndexValue)
|
||||
{
|
||||
// Temporarily disable so we don't capture calls in params
|
||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(mFunctionBindResult, NULL);
|
||||
|
||||
auto origAllowAppendKind = allowAppendKind;
|
||||
|
||||
if (allowAppendKind == BfAllowAppendKind_Infer)
|
||||
allowAppendKind = targetType->IsZeroGap() ? BfAllowAppendKind_ZeroGap : BfAllowAppendKind_Yes;
|
||||
|
||||
static int sCtorCount = 0;
|
||||
sCtorCount++;
|
||||
|
||||
BfMethodMatcher methodMatcher(targetSrc, mModule, "", argValues.mResolvedArgs, methodGenericArguments);
|
||||
methodMatcher.mAllowAppendKind = allowAppendKind;
|
||||
methodMatcher.mBfEvalExprFlags = mBfEvalExprFlags;
|
||||
|
||||
BfTypeVector typeGenericArguments;
|
||||
|
@ -8942,9 +8961,9 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
|||
}
|
||||
|
||||
BfConstructorDeclaration* ctorDecl = (BfConstructorDeclaration*)methodMatcher.mBestMethodDef->mMethodDeclaration;
|
||||
if ((methodMatcher.mBestMethodDef->mHasAppend) && (targetType->IsObject()))
|
||||
if ((methodMatcher.mBestMethodDef->HasAppend()) && (targetType->IsObject()))
|
||||
{
|
||||
if (!allowAppendAlloc)
|
||||
if (allowAppendKind == BfAllowAppendKind_No)
|
||||
{
|
||||
if (mModule->mCurMethodInstance->mMethodDef->mMethodDeclaration == NULL)
|
||||
mModule->Fail("Constructors with append allocations cannot be called from a default constructor. Considering adding an explicit default constructor with the [AllowAppend] specifier.", targetSrc);
|
||||
|
@ -8953,6 +8972,18 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((allowAppendKind == BfAllowAppendKind_Yes) && (methodMatcher.mBestMethodDef->mAppendKind == BfAllowAppendKind_ZeroGap))
|
||||
{
|
||||
BfError* error;
|
||||
if (origAllowAppendKind == BfAllowAppendKind_Infer)
|
||||
error = mModule->Fail(StrFormat("Cannot call ZeroGap constructor for type '%s' because of fields added from type extensions", mModule->TypeToString(targetType).c_str()), targetSrc);
|
||||
else
|
||||
error = mModule->Fail(StrFormat("Cannot call ZeroGap constructor for type '%s' from here", mModule->TypeToString(targetType).c_str()), targetSrc);
|
||||
|
||||
if ((error != NULL) && (methodMatcher.mBestMethodDef->mMethodDeclaration != NULL))
|
||||
mModule->mCompiler->mPassInstance->MoreInfo(StrFormat("See method declaration"), methodMatcher.mBestMethodDef->GetRefNode());
|
||||
}
|
||||
|
||||
BfResolvedArg resolvedArg;
|
||||
if (appendIndexValue != NULL)
|
||||
{
|
||||
|
@ -8975,6 +9006,9 @@ BfTypedValue BfExprEvaluator::MatchConstructor(BfAstNode* targetSrc, BfMethodBou
|
|||
}
|
||||
}
|
||||
|
||||
if (methodMatcher.mAutoFlushAmbiguityErrors)
|
||||
methodMatcher.FlushAmbiguityError(true);
|
||||
|
||||
if (isFailurePass)
|
||||
mModule->Fail(StrFormat("'%s' is inaccessible due to its protection level", mModule->MethodToString(moduleMethodInstance.mMethodInstance).c_str()), targetSrc);
|
||||
prevBindResult.Restore();
|
||||
|
@ -10215,7 +10249,8 @@ BfTypedValue BfExprEvaluator::MatchMethod(BfAstNode* targetSrc, BfMethodBoundExp
|
|||
mResultLocalVar = NULL;
|
||||
mResultFieldInstance = NULL;
|
||||
mResultLocalVarRefNode = NULL;
|
||||
BfTypedValue result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, BfMethodGenericArguments(), resolvedTypeInstance->IsObject());
|
||||
BfTypedValue result = MatchConstructor(targetSrc, methodBoundExpr, structInst, resolvedTypeInstance, argValues, false, BfMethodGenericArguments(),
|
||||
resolvedTypeInstance->IsObject() ? BfAllowAppendKind_Infer : BfAllowAppendKind_No);
|
||||
if ((result) && (!result.mType->IsVoid()))
|
||||
return result;
|
||||
mModule->ValidateAllocation(resolvedTypeInstance, targetSrc);
|
||||
|
@ -14222,7 +14257,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
|
|||
}
|
||||
|
||||
BfResolvedArgs resolvedArgs;
|
||||
MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, BfMethodGenericArguments(), false);
|
||||
MatchConstructor(delegateBindExpr, delegateBindExpr, mResult, useTypeInstance, resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
|
||||
|
||||
auto baseDelegateType = VerifyBaseDelegateType(delegateTypeInstance->mBaseType);
|
||||
auto baseDelegate = mModule->mBfIRBuilder->CreateBitCast(mResult.mValue, mModule->mBfIRBuilder->MapType(baseDelegateType, BfIRPopulateType_Full));
|
||||
|
@ -15951,7 +15986,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
mModule->Fail("Append allocations are only allowed as local variable declarations in the main method body", allocNode);
|
||||
isAppendAlloc = false;
|
||||
}
|
||||
else if (!methodDef->mHasAppend)
|
||||
else if (!methodDef->HasAppend())
|
||||
{
|
||||
mModule->Fail("Append allocations can only be used on constructors with [AllowAppend] specified", allocNode);
|
||||
isAppendAlloc = false;
|
||||
|
@ -16319,11 +16354,11 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
if (rawAutoComplete != NULL)
|
||||
{
|
||||
SetAndRestoreValue<bool> prevCapturing(rawAutoComplete->mIsCapturingMethodMatchInfo, false);
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, false);
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, BfAllowAppendKind_No);
|
||||
}
|
||||
else
|
||||
{
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, false);
|
||||
MatchConstructor(refNode, objCreateExpr, arrayValue, arrayType, resolvedArgs, false, methodGenericArguments, BfAllowAppendKind_No);
|
||||
}
|
||||
|
||||
//TODO: Assert 'length' var is at slot 1
|
||||
|
@ -16506,7 +16541,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
auto checkTypeInst = typeInstance;
|
||||
if (checkTypeInst->IsAnonymousInitializerType())
|
||||
checkTypeInst = checkTypeInst->mBaseType;
|
||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, true);
|
||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, BfAllowAppendKind_Infer);
|
||||
if ((wasCapturingMethodInfo) && (!autoComplete->mIsCapturingMethodMatchInfo))
|
||||
{
|
||||
if (autoComplete->mMethodMatchInfo != NULL)
|
||||
|
@ -16524,7 +16559,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
auto checkTypeInst = typeInstance;
|
||||
if (checkTypeInst->IsAnonymousInitializerType())
|
||||
checkTypeInst = checkTypeInst->mBaseType;
|
||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, true);
|
||||
MatchConstructor(refNode, objCreateExpr, emtpyThis, checkTypeInst, argValues, false, methodGenericArguments, BfAllowAppendKind_Infer);
|
||||
}
|
||||
if (objCreateExpr != NULL)
|
||||
mModule->ValidateAllocation(typeInstance, objCreateExpr->mTypeRef);
|
||||
|
@ -16536,7 +16571,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
allocAlign = typeInstance->mInstAlign;
|
||||
int appendAllocAlign = 0;
|
||||
|
||||
if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->mHasAppend))
|
||||
if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->HasAppend()))
|
||||
{
|
||||
if (!bindResult.mFunc)
|
||||
{
|
||||
|
@ -16736,7 +16771,7 @@ void BfExprEvaluator::CreateObject(BfObjectCreateExpression* objCreateExpr, BfAs
|
|||
thisTypedValue = mModule->Cast(allocNode, thisTypedValue, wantType);
|
||||
}
|
||||
|
||||
if ((bindResult.mMethodInstance->mMethodDef->mHasAppend) && (mResult.mType->IsObject()))
|
||||
if ((bindResult.mMethodInstance->mMethodDef->HasAppend()) && (mResult.mType->IsObject()))
|
||||
{
|
||||
BF_ASSERT(bindResult.mIRArgs[0].IsFake());
|
||||
auto typeInst = mResult.mType->ToTypeInstance();
|
||||
|
@ -18542,7 +18577,7 @@ void BfExprEvaluator::DoInvocation(BfAstNode* target, BfMethodBoundExpression* m
|
|||
else
|
||||
mResult = BfTypedValue(mModule->CreateAlloca(expectingType), expectingType, BfTypedValueKind_TempAddr);
|
||||
|
||||
auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, BfMethodGenericArguments(), false);
|
||||
auto ctorResult = MatchConstructor(target, methodBoundExpr, mResult, expectingType->ToTypeInstance(), argValues, false, BfMethodGenericArguments(), BfAllowAppendKind_No);
|
||||
if ((ctorResult) && (!ctorResult.mType->IsVoid()))
|
||||
mResult = ctorResult;
|
||||
mModule->ValidateAllocation(expectingType, invocationExpr->mTarget);
|
||||
|
@ -23916,7 +23951,7 @@ void BfExprEvaluator::PerformBinaryOperation(BfExpression* leftExpression, BfExp
|
|||
ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||
|
||||
mResult = BfTypedValue(alloca, allocType, true);
|
||||
auto result = MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, BfMethodGenericArguments(), false);
|
||||
auto result = MatchConstructor(opToken, NULL, mResult, allocType, argValues, true, BfMethodGenericArguments(), BfAllowAppendKind_No);
|
||||
if ((result) && (!result.mType->IsVoid()))
|
||||
mResult = result;
|
||||
|
||||
|
|
|
@ -219,6 +219,7 @@ public:
|
|||
BfType* mCheckReturnType;
|
||||
BfMethodType mMethodType;
|
||||
BfCheckedKind mCheckedKind;
|
||||
BfAllowAppendKind mAllowAppendKind;
|
||||
Array<SizedArray<BfUsingFieldData::MemberRef, 1>*>* mUsingLists;
|
||||
bool mHasArgNames;
|
||||
bool mHadExplicitGenericArguments;
|
||||
|
@ -261,7 +262,7 @@ public:
|
|||
void CompareMethods(BfMethodInstance* prevMethodInstance, BfTypeVector* prevGenericArgumentsSubstitute,
|
||||
BfMethodInstance* newMethodInstance, BfTypeVector* genericArgumentsSubstitute,
|
||||
bool* outNewIsBetter, bool* outNewIsWorse, bool allowSpecializeFail);
|
||||
void FlushAmbiguityError();
|
||||
void FlushAmbiguityError(bool useWarning = false);
|
||||
bool IsType(BfTypedValue& val, BfType* type);
|
||||
int GetMostSpecificType(BfType* lhs, BfType* rhs); // 0, 1, or -1
|
||||
|
||||
|
@ -498,7 +499,7 @@ public:
|
|||
void PushArg(BfTypedValue argVal, SizedArrayImpl<BfIRValue>& irArgs, bool disableSplat = false, bool disableLowering = false, bool isIntrinsic = false, bool createCompositeCopy = false);
|
||||
void PushThis(BfAstNode* targetSrc, BfTypedValue callTarget, BfMethodInstance* methodInstance, SizedArrayImpl<BfIRValue>& irArgs, bool skipMutCheck = false);
|
||||
BfTypedValue MatchConstructor(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, BfTypeInstance* targetType,
|
||||
BfResolvedArgs& argValues, bool callCtorBodyOnly, const BfMethodGenericArguments& methodGenericArguments, bool allowAppendAlloc, BfTypedValue* appendIndexValue = NULL);
|
||||
BfResolvedArgs& argValues, bool callCtorBodyOnly, const BfMethodGenericArguments& methodGenericArguments, BfAllowAppendKind allowAppendKind, BfTypedValue* appendIndexValue = NULL);
|
||||
BfTypedValue CheckEnumCreation(BfAstNode* targetSrc, BfTypeInstance* enumType, const StringImpl& caseName, BfResolvedArgs& argValues);
|
||||
BfTypedValue MatchMethod(BfAstNode* targetSrc, BfMethodBoundExpression* methodBoundExpr, BfTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& name,
|
||||
BfResolvedArgs& argValue, const BfMethodGenericArguments& methodGenericArguments, BfCheckedKind checkedKind = BfCheckedKind_NotSet);
|
||||
|
|
|
@ -778,13 +778,13 @@ public:
|
|||
if (typeInst != NULL)
|
||||
{
|
||||
exprEvaluator.ResolveArgValues(argValues);
|
||||
exprEvaluator.MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInst, argValues, false, BfMethodGenericArguments(), true);
|
||||
exprEvaluator.MatchConstructor(objCreateExpr->mTypeRef, objCreateExpr, emtpyThis, typeInst, argValues, false, BfMethodGenericArguments(), BfAllowAppendKind_Infer);
|
||||
}
|
||||
exprEvaluator.mFunctionBindResult = NULL;
|
||||
|
||||
if (bindResult.mMethodInstance != NULL)
|
||||
{
|
||||
if (bindResult.mMethodInstance->mMethodDef->mHasAppend)
|
||||
if (bindResult.mMethodInstance->mMethodDef->HasAppend())
|
||||
{
|
||||
auto calcAppendArgs = bindResult.mIRArgs;
|
||||
BF_ASSERT(calcAppendArgs[0].IsFake());
|
||||
|
@ -4808,9 +4808,9 @@ bool BfModule::TryGetAppendedObjectInfo(BfFieldInstance* fieldInstance, int& dat
|
|||
BfTypedValue emptyThis(mBfIRBuilder->GetFakeVal(), mCurTypeInstance, mCurTypeInstance->IsStruct());
|
||||
|
||||
exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_Comptime;
|
||||
auto ctorResult = exprEvaluator.MatchConstructor(nameRefNode, NULL, emptyThis, fieldTypeInst, resolvedArgs, false, BfMethodGenericArguments(), true);
|
||||
auto ctorResult = exprEvaluator.MatchConstructor(nameRefNode, NULL, emptyThis, fieldTypeInst, resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_Infer);
|
||||
|
||||
if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->mHasAppend))
|
||||
if ((bindResult.mMethodInstance != NULL) && (bindResult.mMethodInstance->mMethodDef->HasAppend()))
|
||||
{
|
||||
auto calcAppendMethodModule = GetMethodInstanceAtIdx(bindResult.mMethodInstance->GetOwner(), bindResult.mMethodInstance->mMethodDef->mIdx + 1, BF_METHODNAME_CALCAPPEND);
|
||||
|
||||
|
@ -4934,7 +4934,7 @@ void BfModule::AppendedObjectInit(BfFieldInstance* fieldInst)
|
|||
mBfIRBuilder->CreateStore(GetConstValue8(BfObjectFlag_AppendAlloc), thisFlagsPtr);
|
||||
}
|
||||
|
||||
exprEvaluator.MatchConstructor(fieldDef->GetNameNode(), NULL, thisValue, fieldInst->mResolvedType->ToTypeInstance(), resolvedArgs, false, BfMethodGenericArguments(), true, &indexVal);
|
||||
exprEvaluator.MatchConstructor(fieldDef->GetNameNode(), NULL, thisValue, fieldInst->mResolvedType->ToTypeInstance(), resolvedArgs, false, BfMethodGenericArguments(), BfAllowAppendKind_Infer, &indexVal);
|
||||
}
|
||||
|
||||
void BfModule::CheckInterfaceMethod(BfMethodInstance* methodInstance)
|
||||
|
@ -7839,7 +7839,7 @@ BfIRValue BfModule::CreateTypeData(BfType* type, BfCreateTypeDataContext& ctx, b
|
|||
paramsVal,
|
||||
GetConstValue(defaultMethod->mReturnType->mTypeId, typeIdType),
|
||||
GetConstValue((int)paramVals.size(), shortType),
|
||||
GetConstValue(methodFlags, shortType),
|
||||
GetConstValue(methodFlags, intType),
|
||||
GetConstValue(methodIdx, intType),
|
||||
GetConstValue(vDataVal, intType),
|
||||
GetConstValue(customAttrIdx, intType),
|
||||
|
@ -10544,7 +10544,7 @@ void BfModule::EmitAppendAlign(int align, int sizeMultiple)
|
|||
else if (mCurMethodInstance->mMethodDef->mMethodType == BfMethodType_Ctor)
|
||||
{
|
||||
auto localVar = mCurMethodState->GetRootMethodState()->mLocals[1];
|
||||
BF_ASSERT(localVar->mName == "appendIdx");
|
||||
BF_ASSERT(localVar->mName == "__appendIdx");
|
||||
auto appendIdxVal = BfTypedValue(localVar->mValue, localVar->mResolvedType, true);
|
||||
BfIRValue appendCurIdx = mBfIRBuilder->CreateLoad(appendIdxVal.mValue);
|
||||
if (align > 1)
|
||||
|
@ -10579,7 +10579,7 @@ void BfModule::EmitAppendAlign(int align, int sizeMultiple)
|
|||
BfIRValue BfModule::AppendAllocFromType(BfType* type, BfIRValue appendSizeValue, int appendAllocAlign, BfIRValue arraySize, int arrayDim, bool isRawArrayAlloc, bool zeroMemory)
|
||||
{
|
||||
auto localVar = mCurMethodState->GetRootMethodState()->mLocals[1];
|
||||
BF_ASSERT(localVar->mName == "appendIdx");
|
||||
BF_ASSERT(localVar->mName == "__appendIdx");
|
||||
BfTypedValue appendIdxVal(localVar->mValue, localVar->mResolvedType, true);
|
||||
|
||||
BfIRValue retValue;
|
||||
|
@ -14043,6 +14043,8 @@ bool BfModule::CompareMethodSignatures(BfMethodInstance* methodA, BfMethodInstan
|
|||
}
|
||||
else if (methodA->mMethodDef->mName != methodB->mMethodDef->mName)
|
||||
return false;
|
||||
if (methodA->mMethodDef->mAppendKind != methodB->mMethodDef->mAppendKind)
|
||||
return false;
|
||||
if (methodA->mMethodDef->mCheckedKind != methodB->mMethodDef->mCheckedKind)
|
||||
return false;
|
||||
if (methodA->mMethodDef->mHasComptime != methodB->mMethodDef->mHasComptime)
|
||||
|
@ -15190,6 +15192,11 @@ BfModuleMethodInstance BfModule::GetMethodInstance(BfTypeInstance* typeInst, BfM
|
|||
methodInstance->mMangleWithIdx = true;
|
||||
}
|
||||
|
||||
if (methodDef->mAppendKind > BfAllowAppendKind_No)
|
||||
{
|
||||
methodInstance->mMangleWithIdx = true;
|
||||
}
|
||||
|
||||
BF_ASSERT(typeInst == methodInstance->GetOwner());
|
||||
|
||||
auto methodDeclaration = methodDef->GetMethodDeclaration();
|
||||
|
@ -17243,6 +17250,24 @@ void BfModule::CalcAppendAlign(BfMethodInstance* methodInst)
|
|||
methodInst->mAppendAllocAlign = 1;
|
||||
}
|
||||
|
||||
BfAllowAppendKind BfModule::GetBaseAllowAppend(BfMethodInstance* curMethodInstance)
|
||||
{
|
||||
auto typeInstance = curMethodInstance->GetOwner();
|
||||
auto methodDef = curMethodInstance->mMethodDef;
|
||||
|
||||
if (methodDef->mAppendKind == BfAllowAppendKind_No)
|
||||
return BfAllowAppendKind_No;
|
||||
|
||||
if ((typeInstance->mInstSize == typeInstance->mBaseType->mInstSize) &&
|
||||
(typeInstance->IsZeroGap()) &&
|
||||
(typeInstance->mBaseType->IsZeroGap()) &&
|
||||
(methodDef->mAppendKind == BfAllowAppendKind_ZeroGap))
|
||||
{
|
||||
return BfAllowAppendKind_ZeroGap;
|
||||
}
|
||||
return BfAllowAppendKind_Yes;
|
||||
}
|
||||
|
||||
BfTypedValue BfModule::TryConstCalcAppend(BfMethodInstance* methodInst, SizedArrayImpl<BfIRValue>& args, bool force)
|
||||
{
|
||||
BP_ZONE("BfModule::TryConstCalcAppend");
|
||||
|
@ -17431,6 +17456,8 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
|||
BF_ASSERT((methodDef->mMethodType == BfMethodType_Ctor) || (methodDef->mMethodType == BfMethodType_CtorCalcAppend));
|
||||
auto ctorDeclaration = (BfConstructorDeclaration*)methodDef->mMethodDeclaration;
|
||||
|
||||
BfAllowAppendKind allowAppendKind = GetBaseAllowAppend(mCurMethodInstance);
|
||||
|
||||
BfCustomAttributes* customAttributes = NULL;
|
||||
defer(delete customAttributes);
|
||||
BfInvocationExpression* ctorInvocation = NULL;
|
||||
|
@ -17477,7 +17504,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
|||
SetAndRestoreValue<bool> prevIgnoreWrites(mBfIRBuilder->mIgnoreWrites, true);
|
||||
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), true);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), allowAppendKind, NULL);
|
||||
}
|
||||
|
||||
if (bindResult.mMethodInstance == NULL)
|
||||
|
@ -17486,7 +17513,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
|||
return BfTypedValue();
|
||||
}
|
||||
|
||||
if (!bindResult.mMethodInstance->mMethodDef->mHasAppend)
|
||||
if (!bindResult.mMethodInstance->mMethodDef->HasAppend())
|
||||
{
|
||||
return BfTypedValue();
|
||||
}
|
||||
|
@ -17524,7 +17551,7 @@ BfTypedValue BfModule::CallBaseCtorCalc(bool constOnly)
|
|||
bindResult.mSkipThis = true;
|
||||
bindResult.mWantsArgs = true;
|
||||
SetAndRestoreValue<BfFunctionBindResult*> prevBindResult(exprEvaluator.mFunctionBindResult, &bindResult);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), true);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), allowAppendKind, NULL);
|
||||
BF_ASSERT(bindResult.mIRArgs[0].IsFake());
|
||||
bindResult.mIRArgs.RemoveAt(0);
|
||||
calcAppendArgs = bindResult.mIRArgs;
|
||||
|
@ -18975,7 +19002,7 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
}
|
||||
}
|
||||
|
||||
if (methodDef->mHasAppend)
|
||||
if (methodDef->HasAppend())
|
||||
{
|
||||
mCurMethodState->mCurAppendAlign = methodInstance->mAppendAllocAlign;
|
||||
}
|
||||
|
@ -19028,16 +19055,18 @@ void BfModule::EmitCtorBody(bool& skipBody)
|
|||
}
|
||||
exprEvaluator.ResolveArgValues(argValues, BfResolveArgsFlag_DeferParamEval);
|
||||
|
||||
BfAllowAppendKind allowAppendKind = GetBaseAllowAppend(mCurMethodInstance);
|
||||
|
||||
BfTypedValue appendIdxVal;
|
||||
if (methodDef->mHasAppend)
|
||||
if (methodDef->HasAppend())
|
||||
{
|
||||
auto localVar = mCurMethodState->GetRootMethodState()->mLocals[1];
|
||||
BF_ASSERT(localVar->mName == "appendIdx");
|
||||
BF_ASSERT(localVar->mName == "__appendIdx");
|
||||
auto intRefType = localVar->mResolvedType;
|
||||
appendIdxVal = BfTypedValue(localVar->mValue, intRefType);
|
||||
mCurMethodState->mCurAppendAlign = 1; // Don't make any assumptions about how the base leaves the alignment
|
||||
}
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), methodDef->mHasAppend, &appendIdxVal);
|
||||
exprEvaluator.MatchConstructor(targetRefNode, NULL, target, targetType, argValues, true, BfMethodGenericArguments(), allowAppendKind, &appendIdxVal);
|
||||
|
||||
if (autoComplete != NULL)
|
||||
{
|
||||
|
@ -25488,6 +25517,12 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
|
|||
silentlyAllow = true;
|
||||
}
|
||||
|
||||
if (checkMethod->mMethodType == BfMethodType_CtorCalcAppend)
|
||||
{
|
||||
// Only use the main ctor as the error method
|
||||
silentlyAllow = true;
|
||||
}
|
||||
|
||||
if (!silentlyAllow)
|
||||
{
|
||||
if ((!methodDef->mName.IsEmpty()) || (checkMethodInstance->mMethodDef->mIsOperator))
|
||||
|
|
|
@ -2020,6 +2020,7 @@ public:
|
|||
void AddMethodToWorkList(BfMethodInstance* methodInstance);
|
||||
bool IsInterestedInMethod(BfTypeInstance* typeInstance, BfMethodDef* methodDef);
|
||||
void CalcAppendAlign(BfMethodInstance* methodInst);
|
||||
BfAllowAppendKind GetBaseAllowAppend(BfMethodInstance* curMethodInstance);
|
||||
BfTypedValue TryConstCalcAppend(BfMethodInstance* methodInst, SizedArrayImpl<BfIRValue>& args, bool force = false);
|
||||
BfTypedValue CallBaseCtorCalc(bool constOnly);
|
||||
void EmitCtorCalcAppend();
|
||||
|
|
|
@ -841,6 +841,9 @@ BfMethodFlags BfMethodInstance::GetMethodFlags()
|
|||
else if (callingConvention == BfIRCallingConv_FastCall)
|
||||
methodFlags = (BfMethodFlags)(methodFlags | BfMethodFlags_FastCall);
|
||||
|
||||
methodFlags = (BfMethodFlags)(methodFlags | (mMethodDef->mAppendKind * BfMethodFlags_AppendBit0));
|
||||
methodFlags = (BfMethodFlags)(methodFlags | (mMethodDef->mCheckedKind * BfMethodFlags_CheckedBit0));
|
||||
|
||||
return methodFlags;
|
||||
}
|
||||
|
||||
|
@ -2704,6 +2707,23 @@ bool BfTypeInstance::IsTypeMemberIncluded(BfTypeDef* typeDef, BfTypeDef* activeT
|
|||
return genericExEntry->mConstraintsPassed;
|
||||
}
|
||||
|
||||
bool BfTypeInstance::IsZeroGap()
|
||||
{
|
||||
BF_ASSERT(mDefineState >= BfTypeDefineState_Defined);
|
||||
|
||||
for (int fieldIdx = mFieldInstances.mSize - 1; fieldIdx >= 0; fieldIdx--)
|
||||
{
|
||||
auto fieldInstance = &mFieldInstances[fieldIdx];
|
||||
auto fieldDef = fieldInstance->GetFieldDef();
|
||||
if (fieldDef == NULL)
|
||||
continue;
|
||||
if ((!fieldDef->mIsStatic) && (fieldDef->mDeclaringType->IsExtension()) && (!fieldInstance->mResolvedType->IsValuelessType()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BfGenericTypeInfo::ReportMemory(MemReporter* memReporter)
|
||||
{
|
||||
memReporter->Add(sizeof(BfGenericTypeInfo));
|
||||
|
|
|
@ -633,6 +633,7 @@ public:
|
|||
virtual bool GetLoweredType(BfTypeUsage typeUsage, BfTypeCode* outTypeCode = NULL, BfTypeCode* outTypeCode2 = NULL) { return false; }
|
||||
virtual BfType* GetUnderlyingType() { return NULL; }
|
||||
virtual bool HasWrappedRepresentation() { return IsWrappableType(); }
|
||||
virtual bool IsZeroGap() { return true; }
|
||||
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) { return true; } // May be 'false' only for generic extensions with constraints
|
||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef) { return true; }
|
||||
virtual bool IsTypeMemberAccessible(BfTypeDef* declaringTypeDef, BfProject* curProject) { return true; }
|
||||
|
@ -2182,6 +2183,7 @@ public:
|
|||
virtual bool IsNullable() override;
|
||||
virtual bool HasVarConstraints();
|
||||
virtual bool IsTypeMemberIncluded(BfTypeDef* declaringTypeDef, BfTypeDef* activeTypeDef = NULL, BfModule* module = NULL) override;
|
||||
virtual bool IsZeroGap() override;
|
||||
|
||||
virtual BfTypeInstance* GetImplBaseType() { return mBaseType; }
|
||||
|
||||
|
|
|
@ -253,7 +253,11 @@ enum BfMethodFlags
|
|||
BfMethodFlags_FastCall = 0x2000,
|
||||
BfMethodFlags_ThisCall = 0x3000,
|
||||
BfMethodFlags_Mutating = 0x4000,
|
||||
BfMethodFlags_Constructor = 0x8000
|
||||
BfMethodFlags_Constructor = 0x8000,
|
||||
BfMethodFlags_AppendBit0 = 0x10000,
|
||||
BfMethodFlags_AppendBit1 = 0x20000,
|
||||
BfMethodFlags_CheckedBit0 = 0x40000,
|
||||
BfMethodFlags_CheckedBit1 = 0x80000,
|
||||
};
|
||||
|
||||
enum BfComptimeMethodFlags
|
||||
|
@ -888,6 +892,15 @@ enum BfComptimeFlags : int8
|
|||
BfComptimeFlag_ConstEval = 4
|
||||
};
|
||||
|
||||
enum BfAllowAppendKind : int8
|
||||
{
|
||||
BfAllowAppendKind_No,
|
||||
BfAllowAppendKind_Yes,
|
||||
BfAllowAppendKind_ZeroGap,
|
||||
|
||||
BfAllowAppendKind_Infer
|
||||
};
|
||||
|
||||
class BfMethodDef : public BfMemberDef
|
||||
{
|
||||
public:
|
||||
|
@ -916,7 +929,7 @@ public:
|
|||
bool mCodeChanged;
|
||||
bool mWantsBody;
|
||||
bool mCLink;
|
||||
bool mHasAppend;
|
||||
BfAllowAppendKind mAppendKind;
|
||||
bool mAlwaysInline;
|
||||
bool mIsNoReturn;
|
||||
bool mIsMutating;
|
||||
|
@ -970,7 +983,7 @@ public:
|
|||
mImportKind = BfImportKind_None;
|
||||
mMethodType = BfMethodType_Normal;
|
||||
mCallingConvention = BfCallingConvention_Unspecified;
|
||||
mHasAppend = false;
|
||||
mAppendKind = BfAllowAppendKind_No;
|
||||
mAlwaysInline = false;
|
||||
mParamNameMap = NULL;
|
||||
mNextWithSameName = NULL;
|
||||
|
@ -980,6 +993,7 @@ public:
|
|||
|
||||
static BfImportKind GetImportKindFromPath(const StringImpl& filePath);
|
||||
bool HasNoThisSplat() { return mIsMutating || mIsNoSplat; }
|
||||
bool HasAppend() { return mAppendKind != BfAllowAppendKind_No; }
|
||||
void Reset();
|
||||
void FreeMembers();
|
||||
BfMethodDeclaration* GetMethodDeclaration();
|
||||
|
|
|
@ -6610,10 +6610,11 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
// int32 mReturnType
|
||||
// int32 mParamCount
|
||||
// int32 mGenericArgCount
|
||||
// int16 mFlags
|
||||
// int32 mFlags
|
||||
// int8 ComptimeMethodFlags
|
||||
// int32 mMethodIdx
|
||||
|
||||
int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+2+1+4);
|
||||
int64 methodHandle = *(int64*)((uint8*)stackPtr + 4+4+4+4+1+4);
|
||||
|
||||
auto methodInstance = mCeMachine->GetMethodInstance(methodHandle);
|
||||
if (methodInstance == NULL)
|
||||
|
@ -6630,9 +6631,9 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8*
|
|||
*(int32*)(stackPtr + 0) = methodInstance->mReturnType->mTypeId;
|
||||
*(int32*)(stackPtr + 4) = methodInstance->GetParamCount();
|
||||
*(int32*)(stackPtr + 4+4) = genericArgCount;
|
||||
*(int16*)(stackPtr + 4+4+4) = methodInstance->GetMethodFlags();
|
||||
*(int32*)(stackPtr + 4+4+4+2) = methodInstance->GetComptimeMethodFlags();
|
||||
*(int32*)(stackPtr + 4+4+4+2+1) = methodInstance->mMethodDef->mIdx;
|
||||
*(int32*)(stackPtr + 4+4+4) = methodInstance->GetMethodFlags();
|
||||
*(int32*)(stackPtr + 4+4+4+4) = methodInstance->GetComptimeMethodFlags();
|
||||
*(int32*)(stackPtr + 4+4+4+4+1) = methodInstance->mMethodDef->mIdx;
|
||||
}
|
||||
else if (checkFunction->mFunctionKind == CeFunctionKind_Method_GetParamInfo)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue