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

Added 'using' field invocation support to debugger

This commit is contained in:
Brian Fiete 2022-07-30 09:41:05 -04:00
parent 14f20f10c8
commit 1a0e28af92
5 changed files with 134 additions and 7 deletions

View file

@ -7489,7 +7489,7 @@ DbgTypedValue DbgExprEvaluator::CreateCall(DbgSubprogram* method, SizedArrayImpl
}
DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue target, bool allowImplicitThis, bool bypassVirtual, const StringImpl& methodName,
const BfSizedArray<ASTREF(BfExpression*)>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments)
const BfSizedArray<ASTREF(BfExpression*)>& arguments, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments, bool& failed)
{
SetAndRestoreValue<String*> prevReferenceId(mReferenceId, NULL);
@ -7983,7 +7983,77 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
if (methodDef == NULL)
{
Fail("Method does not exist", targetSrc);
if (target)
{
std::function<DbgTypedValue(DbgTypedValue)> _CheckUsingFields = [&](DbgTypedValue checkTarget)
{
auto curCheckType = checkTarget.mType->RemoveModifiers();
curCheckType = curCheckType->GetPrimaryType();
curCheckType->PopulateType();
auto nextMember = curCheckType->mMemberList.mHead;
while (nextMember != NULL)
{
auto checkMember = nextMember;
nextMember = checkMember->mNext;
if (checkMember->mName == NULL)
{
//TODO: Check inside anonymous type
DbgTypedValue innerTarget;
addr_target targetPtr = checkTarget.mSrcAddress;
if ((checkTarget.mType != NULL) && (checkTarget.mType->HasPointer()))
targetPtr = checkTarget.mPtr;
innerTarget.mSrcAddress = targetPtr + checkMember->mMemberOffset;
innerTarget.mType = checkMember->mType;
failed = false;
auto result = MatchMethod(targetSrc, innerTarget, false, bypassVirtual, methodName, arguments, methodGenericArguments, failed);
if (!failed)
return result;
}
}
for (auto baseTypeEntry : curCheckType->mBaseTypes)
{
auto baseType = baseTypeEntry->mBaseType;
DbgTypedValue baseTarget = target;
addr_target* ptrRef = NULL;
if ((baseTarget.mPtr != 0) && (checkTarget.mType->HasPointer()))
ptrRef = &baseTarget.mPtr;
else if (baseTarget.mSrcAddress != 0)
ptrRef = &baseTarget.mSrcAddress;
if (ptrRef != NULL)
{
if (baseTypeEntry->mVTableOffset != -1)
{
addr_target vtableAddr = mDebugger->ReadMemory<addr_target>(checkTarget.mPtr);
int32 virtThisOffset = mDebugger->ReadMemory<int32>(vtableAddr + baseTypeEntry->mVTableOffset * sizeof(int32));
*ptrRef += virtThisOffset;
}
else
*ptrRef += baseTypeEntry->mThisOffset;
}
baseTarget.mType = baseType;
auto result = _CheckUsingFields(baseTarget);
if (!failed)
return result;
}
failed = true;
return DbgTypedValue();
};
auto result = _CheckUsingFields(target);
if (!failed)
return result;
}
failed = true;
return DbgTypedValue();
}
@ -8030,7 +8100,7 @@ DbgTypedValue DbgExprEvaluator::MatchMethod(BfAstNode* targetSrc, DbgTypedValue
return CreateCall(targetSrc, callTarget, methodDef, bypassVirtual, arguments, argValues);
}
void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray<ASTREF(BfExpression*)>& args, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments)
void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray<ASTREF(BfExpression*)>& args, BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments, bool& failed)
{
bool allowImplicitThis = false;
BfAstNode* methodNodeSrc = target;
@ -8221,7 +8291,8 @@ void DbgExprEvaluator::DoInvocation(BfAstNode* target, BfSizedArray<ASTREF(BfExp
}*/
}
mResult = MatchMethod(methodNodeSrc, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, args, methodGenericArguments);
mResult = MatchMethod(methodNodeSrc, thisValue, allowImplicitThis, bypassVirtual, targetFunctionName, args, methodGenericArguments, failed);
}
void DbgExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
@ -8235,7 +8306,10 @@ void DbgExprEvaluator::Visit(BfInvocationExpression* invocationExpr)
BfSizedArray<ASTREF(BfAstNode*)>* methodGenericArguments = NULL;
if (invocationExpr->mGenericArgs != NULL)
methodGenericArguments = &invocationExpr->mGenericArgs->mGenericArgs;
DoInvocation(invocationExpr->mTarget, invocationExpr->mArguments, methodGenericArguments);
bool failed = false;
DoInvocation(invocationExpr->mTarget, invocationExpr->mArguments, methodGenericArguments, failed);
if (failed)
Fail("Method does not exist", invocationExpr->mTarget);
if ((wasCapturingMethodInfo) && (!mAutoComplete->mIsCapturingMethodMatchInfo))
{