1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 19:48:20 +02:00

Added CallingConvention support, mangle specifying

This commit is contained in:
Brian Fiete 2020-05-04 07:15:38 -07:00
parent 904f907f1d
commit 61d9edea83
26 changed files with 413 additions and 96 deletions

View file

@ -158,8 +158,35 @@ namespace System
[AttributeUsage(.Method /*2*/ | .StaticField)]
public struct LinkNameAttribute : Attribute
{
public enum MangleKind
{
Beef,
C,
CPP
}
public this(String linkName)
{
}
public this(MangleKind mangleKind)
{
}
}
[AttributeUsage(.Method | .Delegate | .Function)]
public struct CallingConventionAttribute : Attribute
{
public enum Kind
{
Unspecified,
Cdecl,
Stdcall,
Fastcall,
}
public this(Kind callingConvention)
{
}
}

View file

@ -39,6 +39,7 @@ namespace System.Diagnostics
#endif
}
[CallingConvention(.Cdecl)]
static extern void Write(char8* str, int strLen);
public static void Write(String line)

View file

@ -70,6 +70,7 @@ namespace System
return true;
}
[CallingConvention(.Cdecl)]
extern static void ReportTLSMember(int moduleTLSIndex, void* addr, void* markFunc);
static void ReportTLSMember(void* addr, void* markFunc)
{
@ -91,8 +92,11 @@ namespace System
}
#if BF_ENABLE_REALTIME_LEAK_CHECK || BF_DEBUG_ALLOC
[CallingConvention(.Cdecl)]
public extern static void Report();
[CallingConvention(.Cdecl)]
public extern static void Shutdown();
[CallingConvention(.Cdecl)]
public extern static void SetMaxRawDeferredObjectFreePercentage(int maxPercentage);
#else
public static void Report() {}
@ -101,19 +105,31 @@ namespace System
#endif
#if BF_ENABLE_REALTIME_LEAK_CHECK
[CallingConvention(.Cdecl)]
private extern static void Init();
[CallingConvention(.Cdecl)]
public extern static void Collect(bool async = true);
[CallingConvention(.Cdecl)]
private extern static void StopCollecting();
[CallingConvention(.Cdecl)]
private extern static void AddStackMarkableObject(Object obj);
[CallingConvention(.Cdecl)]
private extern static void RemoveStackMarkableObject(Object obj);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
private extern static void MarkAllStaticMembers();
[CallingConvention(.Cdecl)]
private extern static void FindAllTLSMembers();
[CallingConvention(.Cdecl)]
public extern static void DebugDumpLeaks();
[CallingConvention(.Cdecl)]
public extern static void Mark(Object obj);
[CallingConvention(.Cdecl)]
public extern static void Mark(void* ptr, int size);
[CallingConvention(.Cdecl)]
public extern static void SetAutoCollectPeriod(int periodMS); // <= -1 to disable, 0 to constantly run. Defaults to -1
[CallingConvention(.Cdecl)]
public extern static void SetCollectFreeThreshold(int freeBytes); // -1 to disable, 0 to trigger collection after every single free. Defaults to 64MB
[CallingConvention(.Cdecl)]
public extern static void SetMaxPausePercentage(int maxPausePercentage); // 0 = disabled. Defaults to 20.
#else
public static void Collect(bool async = true) {}

View file

@ -25,12 +25,12 @@ namespace System
static class Internal
{
[Intrinsic("cast")]
public static extern Object UnsafeCastToObject(void* ptr);
public static extern Object UnsafeCastToObject(void* ptr);
[Intrinsic("cast")]
public static extern void* UnsafeCastToPtr(Object obj);
[NoReturn]
[CallingConvention(.Cdecl), NoReturn]
public static extern void ThrowIndexOutOfRange(int stackOffset = 0);
[NoReturn]
[CallingConvention(.Cdecl), NoReturn]
public static extern void FatalError(String error, int stackOffset = 0);
[Intrinsic("memcpy")]
public static extern void MemCpy(void* dest, void* src, int length, int32 align = 1, bool isVolatile = false);
@ -46,43 +46,70 @@ namespace System
public static extern void* StdMalloc(int size);
[LinkName("free")]
public static extern void StdFree(void* ptr);
[CallingConvention(.Cdecl)]
public static extern void* VirtualAlloc(int size, bool canExecute, bool canWrite);
[CallingConvention(.Cdecl)]
public static extern int32 CStrLen(char8* charPtr);
[CallingConvention(.Cdecl)]
public static extern int64 GetTickCountMicro();
[CallingConvention(.Cdecl)]
public static extern void BfDelegateTargetCheck(void* target);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void* LoadSharedLibrary(char8* filePath);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void LoadSharedLibraryInto(char8* filePath, void** libDest);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void* GetSharedProcAddress(void* libHandle, char8* procName);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void GetSharedProcAddressInto(void* libHandle, char8* procName, void** procDest);
[CallingConvention(.Cdecl)]
public static extern char8* GetCommandLineArgs();
[CallingConvention(.Cdecl)]
public static extern void ProfilerCmd(char8* str);
[CallingConvention(.Cdecl)]
public static extern void ReportMemory();
[CallingConvention(.Cdecl)]
public static extern void ObjectDynCheck(Object obj, int32 typeId, bool allowNull);
[CallingConvention(.Cdecl)]
public static extern void ObjectDynCheckFailed(Object obj, int32 typeId);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectCreated(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectCreatedEx(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectAllocated(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectAllocatedEx(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern int Dbg_PrepareStackTrace(int baseAllocSize, int maxStackTraceDepth);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectStackInit(Object object, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern Object Dbg_ObjectAlloc(TypeInstance typeInst, int size);
[CallingConvention(.Cdecl)]
public static extern Object Dbg_ObjectAlloc(ClassVData* classVData, int size, int align, int maxStackTraceDepth);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectPreDelete(Object obj);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectPreCustomDelete(Object obj);
[CallingConvention(.Cdecl)]
public static extern void Dbg_MarkObjectDeleted(Object obj);
[CallingConvention(.Cdecl)]
public static extern void* Dbg_RawAlloc(int size);
[CallingConvention(.Cdecl)]
public static extern void* Dbg_RawObjectAlloc(int size);
[CallingConvention(.Cdecl)]
public static extern void* Dbg_RawAlloc(int size, DbgRawAllocData* rawAllocData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_RawFree(void* ptr);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
static extern void Shutdown();
[CallingConvention(.Cdecl)]
static extern void Test_Init(char8* testData);
[CallingConvention(.Cdecl)]
static extern int32 Test_Query();
[CallingConvention(.Cdecl)]
static extern void Test_Finish();
static void* sModuleHandle;

View file

@ -204,12 +204,15 @@ namespace System.Threading
}
public void Suspend() { SuspendInternal(); }
[CallingConvention(.Cdecl)]
private extern void SuspendInternal();
public void Resume() { ResumeInternal(); }
[CallingConvention(.Cdecl)]
private extern void ResumeInternal();
public void Interrupt() { InterruptInternal(); }
[CallingConvention(.Cdecl)]
private extern void InterruptInternal();
public ThreadPriority Priority
@ -217,7 +220,9 @@ namespace System.Threading
get { return (ThreadPriority)GetPriorityNative(); }
set { SetPriorityNative((int32)value); }
}
[CallingConvention(.Cdecl)]
private extern int32 GetPriorityNative();
[CallingConvention(.Cdecl)]
private extern void SetPriorityNative(int32 priority);
extern bool GetIsAlive();
@ -229,6 +234,7 @@ namespace System.Threading
}
}
[CallingConvention(.Cdecl)]
extern bool GetIsThreadPoolThread();
public bool IsThreadPoolThread
{
@ -305,6 +311,7 @@ namespace System.Threading
}
}
[CallingConvention(.Cdecl)]
private static extern Thread GetCurrentThreadNative();
void SetStart(Delegate start, int32 maxStackSize)
@ -324,6 +331,7 @@ namespace System.Threading
delete mDelegate;
}
[CallingConvention(.Cdecl)]
private extern void InternalFinalize();
public bool IsBackground
@ -331,16 +339,18 @@ namespace System.Threading
get { return IsBackgroundNative(); }
set { SetBackgroundNative(value); }
}
[CallingConvention(.Cdecl)]
private extern bool IsBackgroundNative();
[CallingConvention(.Cdecl)]
private extern void SetBackgroundNative(bool isBackground);
[CallingConvention(.Cdecl)]
public extern void SetJoinOnDelete(bool joinOnDelete);
public ThreadState ThreadState
{
get { return (ThreadState)GetThreadStateNative(); }
}
[CallingConvention(.Cdecl)]
private extern int32 GetThreadStateNative();
public void SetName(String name)
@ -363,7 +373,7 @@ namespace System.Threading
if (mName != null)
outName.Append(mName);
}
[CallingConvention(.Cdecl)]
private extern void InformThreadNameChange(String name);
}
}

View file

@ -16,6 +16,7 @@ namespace System
public class Type
{
extern const Type* sTypes;
extern static int32 sTypeCount;
protected const BindingFlags cDefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public;
@ -26,6 +27,14 @@ namespace System
protected TypeCode mTypeCode;
protected uint8 mAlign;
public static TypeId TypeIdEnd
{
get
{
return (.)sTypeCount;
}
}
public int32 Size
{
get

View file

@ -156,12 +156,41 @@ namespace System
[AttributeUsage(.Method /*2*/ | .StaticField)]
public struct LinkNameAttribute : Attribute
{
public enum MangleKind
{
Beef,
C,
CPP
}
public this(String linkName)
{
}
public this(MangleKind mangleKind)
{
}
}
[AttributeUsage(.Method | .Delegate | .Function)]
public struct CallingConventionAttribute : Attribute
{
public enum Kind
{
Unspecified,
Cdecl,
Stdcall,
Fastcall,
}
public this(Kind callingConvention)
{
}
}
[AttributeUsage(.Method | .Delegate | .Function)]
public struct StdCallAttribute : Attribute
{

View file

@ -23,8 +23,9 @@ namespace System.Diagnostics
}
#if !DEBUG
[SkipCall]
[CallingConvention(.Cdecl), SkipCall]
#endif
[CallingConvention(.Cdecl)]
static extern void Write(char8* str, int strLen);
public static void WriteLine(StringView line)

View file

@ -70,6 +70,7 @@ namespace System
return true;
}
[CallingConvention(.Cdecl)]
extern static void ReportTLSMember(int moduleTLSIndex, void* addr, void* markFunc);
static void ReportTLSMember(void* addr, void* markFunc)
{
@ -91,8 +92,11 @@ namespace System
}
#if BF_ENABLE_REALTIME_LEAK_CHECK || BF_DEBUG_ALLOC
[CallingConvention(.Cdecl)]
public extern static void Report();
[CallingConvention(.Cdecl)]
public extern static void Shutdown();
[CallingConvention(.Cdecl)]
public extern static void SetMaxRawDeferredObjectFreePercentage(int maxPercentage);
#else
public static void Report() {}
@ -101,19 +105,31 @@ namespace System
#endif
#if BF_ENABLE_REALTIME_LEAK_CHECK
[CallingConvention(.Cdecl)]
private extern static void Init();
[CallingConvention(.Cdecl)]
public extern static void Collect(bool async = true);
[CallingConvention(.Cdecl)]
private extern static void StopCollecting();
[CallingConvention(.Cdecl)]
private extern static void AddStackMarkableObject(Object obj);
[CallingConvention(.Cdecl)]
private extern static void RemoveStackMarkableObject(Object obj);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
private extern static void MarkAllStaticMembers();
[CallingConvention(.Cdecl)]
private extern static void FindAllTLSMembers();
[CallingConvention(.Cdecl)]
public extern static void DebugDumpLeaks();
[CallingConvention(.Cdecl)]
public extern static void Mark(Object obj);
[CallingConvention(.Cdecl)]
public extern static void Mark(void* ptr, int size);
[CallingConvention(.Cdecl)]
public extern static void SetAutoCollectPeriod(int periodMS); // <= -1 to disable, 0 to constantly run. Defaults to -1
[CallingConvention(.Cdecl)]
public extern static void SetCollectFreeThreshold(int freeBytes); // -1 to disable, 0 to trigger collection after every single free. Defaults to 64MB
[CallingConvention(.Cdecl)]
public extern static void SetMaxPausePercentage(int maxPausePercentage); // 0 = disabled. Defaults to 20.
#else
public static void Collect(bool async = true) {}

View file

@ -17,9 +17,9 @@ namespace System
public static extern Object UnsafeCastToObject(void* ptr);
[Intrinsic("cast")]
public static extern void* UnsafeCastToPtr(Object obj);
[NoReturn]
[CallingConvention(.Cdecl), NoReturn]
public static extern void ThrowIndexOutOfRange(int stackOffset = 0);
[NoReturn]
[CallingConvention(.Cdecl), NoReturn]
public static extern void FatalError(String error, int stackOffset = 0);
[Intrinsic("memcpy")]
public static extern void MemCpy(void* dest, void* src, int length, int32 align = 1, bool isVolatile = false);
@ -35,43 +35,70 @@ namespace System
public static extern void* StdMalloc(int size);
[LinkName("free")]
public static extern void StdFree(void* ptr);
[CallingConvention(.Cdecl)]
public static extern void* VirtualAlloc(int size, bool canExecute, bool canWrite);
[CallingConvention(.Cdecl)]
public static extern int32 CStrLen(char8* charPtr);
[CallingConvention(.Cdecl)]
public static extern int64 GetTickCountMicro();
[CallingConvention(.Cdecl)]
public static extern void BfDelegateTargetCheck(void* target);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void* LoadSharedLibrary(char8* filePath);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void LoadSharedLibraryInto(char8* filePath, void** libDest);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void* GetSharedProcAddress(void* libHandle, char8* procName);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
public static extern void GetSharedProcAddressInto(void* libHandle, char8* procName, void** procDest);
[CallingConvention(.Cdecl)]
public static extern char8* GetCommandLineArgs();
[CallingConvention(.Cdecl)]
public static extern void ProfilerCmd(char8* str);
[CallingConvention(.Cdecl)]
public static extern void ReportMemory();
[CallingConvention(.Cdecl)]
public static extern void ObjectDynCheck(Object obj, int32 typeId, bool allowNull);
[CallingConvention(.Cdecl)]
public static extern void ObjectDynCheckFailed(Object obj, int32 typeId);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectCreated(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectCreatedEx(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectAllocated(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectAllocatedEx(Object obj, int size, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern int Dbg_PrepareStackTrace(int baseAllocSize, int maxStackTraceDepth);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectStackInit(Object object, ClassVData* classVData);
[CallingConvention(.Cdecl)]
public static extern Object Dbg_ObjectAlloc(TypeInstance typeInst, int size);
[CallingConvention(.Cdecl)]
public static extern Object Dbg_ObjectAlloc(ClassVData* classVData, int size, int align, int maxStackTraceDepth);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectPreDelete(Object obj);
[CallingConvention(.Cdecl)]
public static extern void Dbg_ObjectPreCustomDelete(Object obj);
[CallingConvention(.Cdecl)]
public static extern void Dbg_MarkObjectDeleted(Object obj);
[CallingConvention(.Cdecl)]
public static extern void* Dbg_RawAlloc(int size);
[CallingConvention(.Cdecl)]
public static extern void* Dbg_RawObjectAlloc(int size);
[CallingConvention(.Cdecl)]
public static extern void* Dbg_RawAlloc(int size, DbgRawAllocData* rawAllocData);
[CallingConvention(.Cdecl)]
public static extern void Dbg_RawFree(void* ptr);
[AlwaysInclude]
[CallingConvention(.Cdecl), AlwaysInclude]
static extern void Shutdown();
[CallingConvention(.Cdecl)]
static extern void Test_Init(char8* testData);
[CallingConvention(.Cdecl)]
static extern int32 Test_Query();
[CallingConvention(.Cdecl)]
static extern void Test_Finish();
static void* sModuleHandle;

View file

@ -152,8 +152,11 @@ namespace System.Threading
}
}
[CallingConvention(.Cdecl)]
extern void ManualThreadInit();
[CallingConvention(.Cdecl)]
extern void StartInternal();
[CallingConvention(.Cdecl)]
extern void SetStackStart(void* ptr);
public void Start(bool autoDelete = true)
@ -267,6 +270,7 @@ namespace System.Threading
SpinWaitInternal((int32)iterations);
}
[CallingConvention(.Cdecl)]
private static extern bool YieldInternal();
public static bool Yield()

View file

@ -5,13 +5,28 @@ using System.Diagnostics;
using System.Threading;
using System.Collections;
[Obsolete("This is old", false)]
class Bloops
{
}
struct Blurg
{
public static void Hey()
[LinkName(.Empty)]
public static void Hello()
{
}
[CallingConvention(.Cdecl)]
public static void Hey()
{
Hello();
//int a = LinkNameAttribute(.);
}
}
struct StructA
@ -19,6 +34,8 @@ struct StructA
public int mA = 99;
}
/*namespace System
{
extension String

View file

@ -405,6 +405,7 @@ BfCompiler::BfCompiler(BfSystem* bfSystem, bool isResolveOnly)
mIPrintableTypeDef = NULL;
mIHashableTypeDef = NULL;
mLinkNameAttributeTypeDef = NULL;
mCallingConventionAttributeTypeDef = NULL;
mMethodRefTypeDef = NULL;
mNullableTypeDef = NULL;
mOrderedAttributeTypeDef = NULL;
@ -518,6 +519,12 @@ bool BfCompiler::IsTypeUsed(BfType* checkType, BfProject* curProject)
return false;
}
if (checkType->IsFunction())
{
// These don't get their own modules so just assume "always used" at this point
return true;
}
auto module = typeInst->GetModule();
if (module == NULL)
return true;
@ -5983,6 +5990,7 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory)
mIPrintableTypeDef = _GetRequiredType("System.IPrintable");
mIHashableTypeDef = _GetRequiredType("System.IHashable");
mLinkNameAttributeTypeDef = _GetRequiredType("System.LinkNameAttribute");
mCallingConventionAttributeTypeDef = _GetRequiredType("System.CallingConventionAttribute");
mMethodRefTypeDef = _GetRequiredType("System.MethodReference", 1);
mNullableTypeDef = _GetRequiredType("System.Nullable");
mOrderedAttributeTypeDef = _GetRequiredType("System.OrderedAttribute");

View file

@ -377,6 +377,7 @@ public:
BfTypeDef* mAttributeTypeDef;
BfTypeDef* mAttributeUsageAttributeTypeDef;
BfTypeDef* mLinkNameAttributeTypeDef;
BfTypeDef* mCallingConventionAttributeTypeDef;
BfTypeDef* mOrderedAttributeTypeDef;
BfTypeDef* mInlineAttributeTypeDef;
BfTypeDef* mCLinkAttributeTypeDef;

View file

@ -328,6 +328,8 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch
if ((arg.mArgFlags & BfArgFlag_DeferredEval) != 0)
{
mExpectingType = arg.mExpectedType;
if (mExpectingType == NULL)
mExpectingType = wantType;
if (auto expr = BfNodeDynCast<BfExpression>(argExpr))
argValue = Resolve(expr, mExpectingType);

View file

@ -4504,7 +4504,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
firstArg = irArgs[0];
auto methodInstOwner = methodInstance->GetOwner();
auto expectCallingConvention = mModule->GetIRCallingConvention(methodInstOwner, methodDef);
auto expectCallingConvention = mModule->GetIRCallingConvention(methodInstance);
if ((methodInstOwner->IsFunction()) && (methodInstance->GetParamCount() > 0) && (methodInstance->GetParamName(0) == "this"))
{
auto paramType = methodInstance->GetParamType(0);
@ -4563,7 +4563,7 @@ BfTypedValue BfExprEvaluator::CreateCall(BfMethodInstance* methodInstance, BfIRV
{
if (paramType->IsStruct())
{
if ((!doingThis) || (!methodDef->mIsMutating && !methodDef->mNoSplat))
if ((!doingThis) || (!methodDef->mIsMutating && methodInstance->AllowsSplatting()))
{
auto loweredTypeCode = paramType->GetLoweredType();
if (loweredTypeCode != BfTypeCode_None)
@ -4955,7 +4955,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth
if (argVal.mType->IsValuelessType())
return;
if ((argVal.mType->IsTypedPrimitive()) && (methodDef->HasNoThisSplat()))
if ((argVal.mType->IsTypedPrimitive()) && (!methodInstance->AllowsThisSplatting()))
{
argVal = mModule->MakeAddressable(argVal);
irArgs.push_back(argVal.mValue);
@ -4963,7 +4963,7 @@ void BfExprEvaluator::PushThis(BfAstNode* targetSrc, BfTypedValue argVal, BfMeth
}
auto thisType = methodInstance->GetParamType(-1);
PushArg(argVal, irArgs, methodDef->HasNoThisSplat(), thisType->IsPointer());
PushArg(argVal, irArgs, !methodInstance->AllowsThisSplatting(), thisType->IsPointer());
}
void BfExprEvaluator::FinishDeferredEvals(SizedArrayImpl<BfResolvedArg>& argValues)
@ -5007,10 +5007,10 @@ void BfExprEvaluator::AddCallDependencies(BfMethodInstance* methodInstance)
BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, const BfTypedValue& inTarget, const BfTypedValue& origTarget, BfMethodDef* methodDef, BfModuleMethodInstance moduleMethodInstance, bool bypassVirtual, SizedArrayImpl<BfResolvedArg>& argValues, bool skipThis)
{
static int sCallIdx = 0;
if (!mModule->mCompiler->mIsResolveOnly)
if (!mModule->mCompiler->mIsResolveOnly)
sCallIdx++;
int callIdx = sCallIdx;
if (callIdx == 0x0000042B)
if (callIdx == 7462)
{
NOP;
}
@ -9195,7 +9195,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
return;
}
bool hasIncompatibleCallingConventions = !mModule->mSystem->IsCompatibleCallingConvention(methodInstance->mMethodDef->mCallingConvention, bindMethodInstance->mMethodDef->mCallingConvention);
bool hasIncompatibleCallingConventions = !mModule->mSystem->IsCompatibleCallingConvention(methodInstance->mCallingConvention, bindMethodInstance->mCallingConvention);
auto _GetInvokeMethodName = [&]()
{
@ -9359,7 +9359,7 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
bool isStructTarget = (target) && (target.mType->IsStruct());
bool bindCapturesThis = bindMethodInstance->HasThis() && !isStructTarget;
bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (!bindMethodInstance->mMethodDef->mNoSplat);
bool needsSplat = (isStructTarget) && (!bindMethodInstance->mMethodDef->mIsMutating) && (bindMethodInstance->AllowsSplatting());
bool captureThisByValue = isStructTarget;
if (bindMethodInstance->mMethodDef->mIsLocalMethod)
{
@ -9529,8 +9529,10 @@ void BfExprEvaluator::Visit(BfDelegateBindExpression* delegateBindExpr)
funcValue = mModule->mBfIRBuilder->CreateFunction(funcType, BfIRLinkageType_External, methodName);
auto srcCallingConv = mModule->GetIRCallingConvention(methodInstance);
if ((!hasThis) && (methodInstance->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
if ((!hasThis) && (methodInstance->mCallingConvention == BfCallingConvention_Stdcall))
srcCallingConv = BfIRCallingConv_StdCall;
else if (methodInstance->mCallingConvention == BfCallingConvention_Fastcall)
srcCallingConv = BfIRCallingConv_FastCall;
mModule->mBfIRBuilder->SetFuncCallingConv(funcValue, srcCallingConv);
mModule->mBfIRBuilder->SetActiveFunction(funcValue);

View file

@ -346,6 +346,7 @@ enum BfIRCallingConv
BfIRCallingConv_ThisCall,
BfIRCallingConv_StdCall,
BfIRCallingConv_CDecl,
BfIRCallingConv_FastCall
};
enum BfIRParamType : uint8

View file

@ -180,6 +180,8 @@ static int GetLLVMCallingConv(BfIRCallingConv callingConv)
llvmCallingConv = llvm::CallingConv::X86_ThisCall;
else if (callingConv == BfIRCallingConv_StdCall)
llvmCallingConv = llvm::CallingConv::X86_StdCall;
else if (callingConv == BfIRCallingConv_FastCall)
llvmCallingConv = llvm::CallingConv::X86_FastCall;
else if (callingConv == BfIRCallingConv_CDecl)
llvmCallingConv = llvm::CallingConv::C;
return llvmCallingConv;

View file

@ -355,7 +355,8 @@ void BfGNUMangler::MangleTypeInst(MangleContext& mangleContext, StringImpl& name
auto typeDef = useTypeInst->mTypeDef;
FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom), curMatchIdx, matchFailed);
if (!mangleContext.mCPPMangle)
FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeInst->mModule->mSystem->mBfAtom), curMatchIdx, matchFailed);
for (int i = 0; i < typeDef->mNamespace.mSize; i++)
FindOrCreateNameSub(mangleContext, name, NameSubstitute(NameSubstitute::Kind_NamespaceAtom, typeDef->mNamespace.mParts[i]), curMatchIdx, matchFailed);
@ -667,13 +668,42 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
return methodInst->mMethodDef->mName;
}
auto methodDef = methodInst->mMethodDef;
auto typeInst = methodInst->GetOwner();
auto typeDef = typeInst->mTypeDef;
MangleContext mangleContext;
mangleContext.mModule = methodInst->GetOwner()->mModule;
mangleContext.mCCompat = methodInst->mMethodDef->mIsExtern;
//auto substituteListPtr = doSubstitute ? &mangleContext.mSubstituteList : NULL;
if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
mangleContext.mCCompat = true;
auto customAttributes = methodInst->GetCustomAttributes();
if (customAttributes != NULL)
{
auto linkNameAttr = customAttributes->Get(typeInst->mModule->mCompiler->mLinkNameAttributeTypeDef);
if (linkNameAttr != NULL)
{
if (linkNameAttr->mCtorArgs.size() == 1)
{
if (typeInst->mModule->TryGetConstString(typeInst->mConstHolder, linkNameAttr->mCtorArgs[0], name))
if (!name.IsWhitespace())
return name;
auto typeInst = methodInst->GetOwner();
auto methodDef = methodInst->mMethodDef;
auto constant = typeInst->mConstHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
if (constant != NULL)
{
if (constant->mInt32 == 1) // C
{
name += methodInst->mMethodDef->mName;
return name;
}
else if (constant->mInt32 == 2) // CPP
{
mangleContext.mCPPMangle = true;
}
}
}
}
}
bool mangledMethodIdx = false;
bool prefixLen = false;
@ -862,8 +892,8 @@ String BfGNUMangler::Mangle(BfMethodInstance* methodInst)
{
addProjectName = true;
if ((methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Cdecl) ||
(methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
if ((methodInst->mCallingConvention == BfCallingConvention_Cdecl) ||
(methodInst->mCallingConvention == BfCallingConvention_Stdcall))
{
addProjectName = false;
addIndex = false;
@ -1308,7 +1338,8 @@ void BfMSMangler::Mangle(MangleContext& mangleContext, StringImpl& name, BfTypeI
FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, namePart));
}
FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, useModule->mSystem->mBfAtom));
if (!mangleContext.mCPPMangle)
FindOrCreateNameSub(mangleContext, name, NameSubstitute(BfMangler::NameSubstitute::Kind_NamespaceAtom, useModule->mSystem->mBfAtom));
}
name += '@';
@ -1739,7 +1770,8 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho
MangleContext mangleContext;
mangleContext.mIs64Bit = is64Bit;
mangleContext.mModule = methodInst->GetOwner()->mModule;
mangleContext.mCCompat = methodInst->mMethodDef->mIsExtern;
if (methodInst->mCallingConvention != BfCallingConvention_Unspecified)
mangleContext.mCCompat = true;
auto customAttributes = methodInst->GetCustomAttributes();
if (customAttributes != NULL)
{
@ -1749,7 +1781,22 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho
if (linkNameAttr->mCtorArgs.size() == 1)
{
if (typeInst->mModule->TryGetConstString(typeInst->mConstHolder, linkNameAttr->mCtorArgs[0], name))
return;
if (!name.IsWhitespace())
return;
auto constant = typeInst->mConstHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
if (constant != NULL)
{
if (constant->mInt32 == 1) // C
{
name += methodInst->mMethodDef->mName;
return;
}
else if (constant->mInt32 == 2) // CPP
{
mangleContext.mCPPMangle = true;
}
}
}
}
}
@ -1965,8 +2012,8 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho
{
addProjectName = true;
if ((methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Cdecl) ||
(methodInst->mMethodDef->mCallingConvention == BfCallingConvention_Stdcall))
if ((methodInst->mCallingConvention == BfCallingConvention_Cdecl) ||
(methodInst->mCallingConvention == BfCallingConvention_Stdcall))
{
addProjectName = false;
addIndex = false;
@ -2040,7 +2087,7 @@ void BfMSMangler::Mangle(StringImpl& name, bool is64Bit, BfMethodInstance* metho
name += qualifier;
}
auto callingConvention = mangleContext.mModule->GetIRCallingConvention(typeInst, methodDef);
auto callingConvention = mangleContext.mModule->GetIRCallingConvention(methodInst);
char callingConv = 'A';
if (callingConvention == BfIRCallingConv_StdCall)

View file

@ -93,6 +93,7 @@ public:
public:
BfModule* mModule;
bool mCCompat;
bool mCPPMangle;
bool mInArgs;
bool mPrefixObjectPointer;
llvm::SmallVector<NameSubstitute, 32> mSubstituteList;
@ -102,6 +103,7 @@ public:
{
mModule = NULL;
mCCompat = false;
mCPPMangle = false;
mInArgs = false;
mPrefixObjectPointer = false;
}
@ -136,6 +138,7 @@ public:
BfModule* mModule;
bool mCCompat;
bool mCPPMangle;
bool mIs64Bit;
SizedArray<NameSubstitute, 10> mSubstituteList;
SizedArray<BfType*, 10> mSubstituteTypeList;
@ -151,6 +154,7 @@ public:
mModule = NULL;
mCCompat = false;
mIs64Bit = false;
mCPPMangle = false;
mWantsGroupStart = false;
mInArgs = false;
mInRet = false;

View file

@ -5862,6 +5862,8 @@ BfIRValue BfModule::CreateTypeData(BfType* type, Dictionary<int, int>& usedStrin
methodFlags = (MethodFlags)(methodFlags | MethodFlags_ThisCall);
else if (callingConvention == BfIRCallingConv_StdCall)
methodFlags = (MethodFlags)(methodFlags | MethodFlags_StdCall);
else if (callingConvention == BfIRCallingConv_FastCall)
methodFlags = (MethodFlags)(methodFlags | MethodFlags_FastCall);
int customAttrIdx = _HandleCustomAttrs(methodCustomAttributes);
@ -13276,7 +13278,7 @@ void BfModule::CreateDelegateInvokeMethod()
BfIRValue nonStaticResult;
BfIRValue staticResult;
auto callingConv = GetIRCallingConvention(mCurTypeInstance, mCurMethodInstance->mMethodDef);
auto callingConv = GetIRCallingConvention(mCurMethodInstance);
/// Non-static invocation
{
@ -14041,7 +14043,7 @@ BfIRValue BfModule::CreateDllImportGlobalVar(BfMethodInstance* methodInstance, b
auto typeInstance = methodInstance->GetOwner();
bool foundDllImportAttr = false;
BfCallingConvention callingConvention = methodInstance->mMethodDef->mCallingConvention;
BfCallingConvention callingConvention = methodInstance->mCallingConvention;
for (auto customAttr : methodInstance->GetCustomAttributes()->mAttributes)
{
if (customAttr.mType->mTypeDef->mFullName.ToString() == "System.ImportAttribute")
@ -14107,7 +14109,7 @@ void BfModule::CreateDllImportMethod()
mBfIRBuilder->CreateCall(loadSharedLibsFunc, SizedArray<BfIRValue, 0>());
}
auto callingConvention = GetIRCallingConvention(mCurTypeInstance, mCurMethodInstance->mMethodDef);
auto callingConvention = GetIRCallingConvention(mCurMethodInstance);
BfIRType returnType;
SizedArray<BfIRType, 8> paramTypes;
@ -14126,6 +14128,8 @@ void BfModule::CreateDllImportMethod()
auto result = mBfIRBuilder->CreateCall(funcVal, args);
if (callingConvention == BfIRCallingConv_StdCall)
mBfIRBuilder->SetCallCallingConv(result, BfIRCallingConv_StdCall);
else if (callingConvention == BfIRCallingConv_FastCall)
mBfIRBuilder->SetCallCallingConv(result, BfIRCallingConv_FastCall);
else
mBfIRBuilder->SetCallCallingConv(result, BfIRCallingConv_CDecl);
if (allowTailCall)
@ -14143,18 +14147,6 @@ void BfModule::CreateDllImportMethod()
}
}
BfIRCallingConv BfModule::GetIRCallingConvention(BfTypeInstance* typeInst, BfMethodDef* methodDef)
{
if ((mCompiler->mOptions.mMachineType != BfMachineType_x86) || (mCompiler->mOptions.mPlatformType != BfPlatformType_Windows))
return BfIRCallingConv_CDecl;
if (methodDef->mCallingConvention == BfCallingConvention_Stdcall)
return BfIRCallingConv_StdCall;
if ((!methodDef->mIsStatic) && (!typeInst->IsValuelessType()) &&
((!typeInst->IsSplattable()) || (methodDef->HasNoThisSplat())))
return BfIRCallingConv_ThisCall;
return BfIRCallingConv_CDecl;
}
BfIRCallingConv BfModule::GetIRCallingConvention(BfMethodInstance* methodInstance)
{
auto methodDef = methodInstance->mMethodDef;
@ -14163,7 +14155,19 @@ BfIRCallingConv BfModule::GetIRCallingConvention(BfMethodInstance* methodInstanc
owner = methodInstance->GetParamType(-1)->ToTypeInstance();
if (owner == NULL)
owner = methodInstance->GetOwner();
return GetIRCallingConvention(owner, methodInstance->mMethodDef);
if ((mCompiler->mOptions.mMachineType != BfMachineType_x86) || (mCompiler->mOptions.mPlatformType != BfPlatformType_Windows))
return BfIRCallingConv_CDecl;
if (methodInstance->mCallingConvention == BfCallingConvention_Stdcall)
return BfIRCallingConv_StdCall;
if (methodInstance->mCallingConvention == BfCallingConvention_Fastcall)
return BfIRCallingConv_FastCall;
if ((!methodDef->mIsStatic) && (!owner->IsValuelessType()) &&
((!owner->IsSplattable()) || (methodDef->HasNoThisSplat())))
return BfIRCallingConv_ThisCall;
return BfIRCallingConv_CDecl;
//return GetIRCallingConvention(owner, methodInstance->mMethodDef);
}
void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined)
@ -14214,6 +14218,11 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
argIdx++;
}
if (methodDef->mName == "Hello")
{
NOP;
}
while (argIdx < argCount)
{
while ((paramIdx != -1) && (methodInstance->IsParamSkipped(paramIdx)))
@ -14230,15 +14239,15 @@ void BfModule::SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func
resolvedTypeRef = mCurMethodState->mClosureState->mClosureType;
else
resolvedTypeRef = methodInstance->GetOwner();
isSplattable = (resolvedTypeRef->IsSplattable()) && (!methodDef->HasNoThisSplat());
isSplattable = (resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsThisSplatting());
}
else if (!methodDef->mNoSplat)
else
{
paramName = methodInstance->GetParamName(paramIdx);
resolvedTypeRef = methodInstance->GetParamType(paramIdx);
if (resolvedTypeRef->IsMethodRef())
isSplattable = true;
else if (resolvedTypeRef->IsSplattable())
else if ((resolvedTypeRef->IsSplattable()) && (methodInstance->AllowsSplatting()))
{
auto resolvedTypeInst = resolvedTypeRef->ToTypeInstance();
if ((resolvedTypeInst != NULL) && (resolvedTypeInst->mIsCRepr))
@ -15268,9 +15277,9 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
paramVar->mValue = mBfIRBuilder->GetArgument(argIdx);
else
paramVar->mValue = mBfIRBuilder->GetFakeVal();
if ((thisType->IsComposite()) && (!methodDef->HasNoThisSplat()))
if (thisType->IsComposite())
{
if (thisType->IsSplattable())
if ((thisType->IsSplattable()) && (methodInstance->AllowsThisSplatting()))
paramVar->mIsSplat = true;
else
paramVar->mIsLowered = thisType->GetLoweredType() != BfTypeCode_None;
@ -15359,7 +15368,7 @@ void BfModule::ProcessMethod_SetupParams(BfMethodInstance* methodInstance, BfTyp
// crepr splat is always splat
paramVar->mIsSplat = true;
}
else
else if (methodInstance->AllowsSplatting())
{
int splatCount = resolvedType->GetSplatCount();
if (argIdx + splatCount <= mCompiler->mOptions.mMaxSplatRegs)
@ -16845,8 +16854,6 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
else
{
bool handled = false;
//if ((!isThis) || (!methodDef->mIsMutating && !methodDef->mNoSplat))
if (paramVar->mIsLowered)
{
auto loweredTypeCode = paramVar->mResolvedType->GetLoweredType();
@ -17223,10 +17230,13 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup)
mCurMethodState->mIgnoreObjectAccessCheck = true;
}
auto customAttributes = methodInstance->GetCustomAttributes();
if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mDisableObjectAccessChecksAttributeTypeDef)))
mCurMethodState->mIgnoreObjectAccessCheck = true;
if ((customAttributes != NULL) && (customAttributes->Contains(mCompiler->mDisableChecksAttributeTypeDef)))
mCurMethodState->mDisableChecks = true;
if (customAttributes != NULL)
{
if (customAttributes->Contains(mCompiler->mDisableObjectAccessChecksAttributeTypeDef))
mCurMethodState->mIgnoreObjectAccessCheck = true;
if (customAttributes->Contains(mCompiler->mDisableChecksAttributeTypeDef))
mCurMethodState->mDisableChecks = true;
}
if ((methodDef->mMethodType == BfMethodType_CtorNoBody) && (!methodDef->mIsStatic) &&
((methodInstance->mChainType == BfMethodChainType_ChainHead) || (methodInstance->mChainType == BfMethodChainType_None)))
@ -18747,7 +18757,8 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance)
{
auto methodDef = methodInstance->mMethodDef;
if (methodInstance->GetCustomAttributes() != NULL)
auto customAttributes = methodInstance->GetCustomAttributes();
if (customAttributes != NULL)
return;
auto methodDeclaration = methodDef->GetMethodDeclaration();
@ -18770,6 +18781,29 @@ void BfModule::GetMethodCustomAttributes(BfMethodInstance* methodInstance)
methodInstance->mMethodInfoEx->mMethodCustomAttributes = new BfMethodCustomAttributes();
methodInstance->mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes = GetCustomAttributes(propertyMethodDeclaration->mAttributes, BfAttributeTargets_Method);
}
customAttributes = methodInstance->GetCustomAttributes();
if (customAttributes == NULL)
{
auto owner = methodInstance->GetOwner();
if ((owner->IsDelegate()) || (owner->IsFunction()))
customAttributes = owner->mCustomAttributes;
}
methodInstance->mCallingConvention = methodDef->mCallingConvention;
if (customAttributes != NULL)
{
auto linkNameAttr = customAttributes->Get(typeInstance->mModule->mCompiler->mCallingConventionAttributeTypeDef);
if (linkNameAttr != NULL)
{
if (linkNameAttr->mCtorArgs.size() == 1)
{
auto constant = typeInstance->mConstHolder->GetConstant(linkNameAttr->mCtorArgs[0]);
if (constant != NULL)
methodInstance->mCallingConvention = (BfCallingConvention)constant->mInt32;
}
}
}
}
void BfModule::SetupIRFunction(BfMethodInstance* methodInstance, StringImpl& mangledName, bool isTemporaryFunc, bool* outIsIntrinsic)
@ -19712,7 +19746,7 @@ void BfModule::DoMethodDeclaration(BfMethodDeclaration* methodDeclaration, bool
{
methodParam.mIsSplat = true;
}
else if (methodParam.mResolvedType->IsComposite())
else if ((methodParam.mResolvedType->IsComposite()) && (methodInstance->AllowsSplatting()))
{
PopulateType(methodParam.mResolvedType, BfPopulateType_Data);
if (methodParam.mResolvedType->IsSplattable())

View file

@ -1731,7 +1731,6 @@ public:
void CreateStaticCtor();
BfIRValue CreateDllImportGlobalVar(BfMethodInstance* methodInstance, bool define = false);
void CreateDllImportMethod();
BfIRCallingConv GetIRCallingConvention(BfTypeInstance* typeInst, BfMethodDef* methodDef);
BfIRCallingConv GetIRCallingConvention(BfMethodInstance* methodInstance);
void SetupIRMethod(BfMethodInstance* methodInstance, BfIRFunction func, bool isInlined);
void EmitCtorBody(bool& skipBody);

View file

@ -7275,8 +7275,16 @@ BfType* BfModule::ResolveTypeRef(BfTypeReference* typeRef, BfPopulateType popula
auto resolvedType = ResolveTypeRef(refTypeRef->mElementType, BfPopulateType_Identity, BfResolveTypeRefFlag_AllowGenericParamConstValue);
if (resolvedType != NULL)
{
if ((resolvedType->IsComposite()) || (resolvedType->IsGenericParam()))
if ((resolvedType->IsValueType()) || (resolvedType->IsGenericParam()))
needsRefWrap = true;
if ((InDefinitionSection()) && (!resolvedType->IsGenericParam()))
{
if (!resolvedType->IsValueType())
Warn(0, StrFormat("Specified 'mut' has no effect on '%s' since reference types are always mutable", TypeToString(resolvedType).c_str()), refTypeRef->mRefToken);
else
Warn(0, "Use 'mut' for generic arguments which may or may not be reference types. Consider using 'ref' here, instead.", refTypeRef->mRefToken);
}
}
if (!needsRefWrap)

View file

@ -655,6 +655,20 @@ bool BfMethodInstance::IsTestMethod()
(mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes != NULL) && (mMethodInfoEx->mMethodCustomAttributes->mCustomAttributes->Contains(GetOwner()->mModule->mCompiler->mTestAttributeTypeDef));
}
bool BfMethodInstance::AllowsSplatting()
{
if (mCallingConvention != BfCallingConvention_Unspecified)
return false;
return !mMethodDef->mNoSplat;
}
bool BfMethodInstance::AllowsThisSplatting()
{
if (mCallingConvention != BfCallingConvention_Unspecified)
return false;
return !mMethodDef->HasNoThisSplat();
}
bool BfMethodInstance::HasThis()
{
if (mMethodDef->mIsStatic)
@ -723,7 +737,7 @@ BfType* BfMethodInstance::GetParamType(int paramIdx, bool useResolvedType)
return mMethodInfoEx->mClosureInstanceInfo->mThisOverride;
BF_ASSERT(!mMethodDef->mIsStatic);
auto owner = mMethodInstanceGroup->mOwner;
if ((owner->IsValueType()) && ((mMethodDef->mIsMutating) || (mMethodDef->mNoSplat)))
if ((owner->IsValueType()) && ((mMethodDef->mIsMutating) || (!AllowsSplatting())))
return owner->mModule->CreatePointerType(owner);
return owner;
}
@ -743,7 +757,7 @@ bool BfMethodInstance::GetParamIsSplat(int paramIdx)
{
BF_ASSERT(!mMethodDef->mIsStatic);
auto owner = mMethodInstanceGroup->mOwner;
if ((owner->IsValueType()) && (mMethodDef->mIsMutating || mMethodDef->mNoSplat))
if ((owner->IsValueType()) && (mMethodDef->mIsMutating || !AllowsSplatting()))
return false;
return owner->mIsSplattable;
}
@ -947,7 +961,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
if ((checkType->IsValuelessType()) && (!checkType->IsMethodRef()))
continue;
bool doSplat = true;
bool doSplat = false;
if (checkType->IsMethodRef())
{
doSplat = true;
@ -956,7 +970,7 @@ void BfMethodInstance::GetIRFunctionInfo(BfModule* module, BfIRType& returnType,
{
doSplat = false;
}
else
else if ((paramIdx == -1) ? AllowsThisSplatting() : AllowsSplatting())
{
int splatCount = checkType->GetSplatCount();
doSplat = ((checkType->IsSplattable()) && ((paramIdx != -1) || (!mMethodDef->mIsMutating)));
@ -3789,8 +3803,15 @@ String BfTypeUtils::TypeToString(BfTypeReference* typeRef)
return name;
}
if (auto constTypeRef = BfNodeDynCast<BfConstExprTypeRef>(typeRef))
{
String name = "const ";
name += constTypeRef->mConstExpr->ToString();
return name;
}
BF_DBG_FATAL("Not implemented");
return "???";
return typeRef->ToString();
}
bool BfTypeUtils::TypeEquals(BfType* typeA, BfType* typeB, BfType* selfType)

View file

@ -747,6 +747,7 @@ public:
bool mDisallowCalling:1;
bool mIsGenericMethodInstance:1;
BfMethodChainType mChainType;
BfCallingConvention mCallingConvention;
BfMethodInstanceGroup* mMethodInstanceGroup;
BfMethodDef* mMethodDef;
BfType* mReturnType;
@ -781,6 +782,7 @@ public:
mDisallowCalling = false;
mIsGenericMethodInstance = false;
mChainType = BfMethodChainType_None;
mCallingConvention = BfCallingConvention_Unspecified;
mMethodInstanceGroup = NULL;
mMethodDef = NULL;
mReturnType = NULL;
@ -817,6 +819,8 @@ public:
bool AlwaysInline();
BfImportCallKind GetImportCallKind();
bool IsTestMethod();
bool AllowsSplatting();
bool AllowsThisSplatting();
int GetParamCount();
int GetImplicitParamCount();
void GetParamName(int paramIdx, StringImpl& name);