2022-03-08 06:27:06 -08:00
# include "CeDebugger.h"
# include "CeMachine.h"
# include "BfCompiler.h"
# include "../DebugManager.h"
# include "BeefySysLib/util/BeefPerf.h"
# include "BfParser.h"
# include "BfReducer.h"
# include "BeefySysLib/util/UTF8.h"
# include "BfUtil.h"
# include "BfExprEvaluator.h"
# include "BeefySysLib/util/BitSet.h"
# include "../DebugVisualizers.h"
2022-03-15 16:33:30 -07:00
# include "BfAutoComplete.h"
# include "BfDemangler.h"
2022-03-08 06:27:06 -08:00
USING_NS_BF ;
static addr_ce DecodeTargetDataPtr ( const char * & strRef )
{
addr_ce val = ( addr_ce ) stouln ( strRef , sizeof ( addr_ce ) * 2 ) ;
strRef + = sizeof ( addr_ce ) * 2 ;
return val ;
}
//////////////////////////////////////////////////////////////////////////
2022-03-15 16:33:30 -07:00
CeBreakpointCondition : : ~ CeBreakpointCondition ( )
{
delete mDbgEvaluationContext ;
}
//////////////////////////////////////////////////////////////////////////
CeBreakpoint : : ~ CeBreakpoint ( )
{
delete mCondition ;
}
//////////////////////////////////////////////////////////////////////////
2022-03-08 06:27:06 -08:00
CePendingExpr : : CePendingExpr ( )
{
mThreadId = - 1 ;
mCallStackIdx = - 1 ;
2022-03-15 16:33:30 -07:00
mPassInstance = NULL ;
2022-03-08 06:27:06 -08:00
mParser = NULL ;
mCursorPos = - 1 ;
mExprNode = NULL ;
mIdleTicks = 0 ;
mExplitType = NULL ;
mExpressionFlags = DwEvalExpressionFlag_None ;
2022-03-15 16:33:30 -07:00
mDone = false ;
2022-03-08 06:27:06 -08:00
}
CePendingExpr : : ~ CePendingExpr ( )
{
delete mParser ;
2022-03-15 16:33:30 -07:00
delete mPassInstance ;
2022-03-08 06:27:06 -08:00
}
//////////////////////////////////////////////////////////////////////////
CeEvaluationContext : : CeEvaluationContext ( CeDebugger * winDebugger , const StringImpl & expr , CeFormatInfo * formatInfo , BfTypedValue contextValue )
{
Init ( winDebugger , expr , formatInfo , contextValue ) ;
}
void CeEvaluationContext : : Init ( CeDebugger * ceDebugger , const StringImpl & expr , CeFormatInfo * formatInfo , BfTypedValue contextValue )
{
mDebugger = ceDebugger ;
mCallStackIdx = 0 ;
mParser = NULL ;
mReducer = NULL ;
mPassInstance = NULL ;
mExprEvaluator = NULL ;
mExprNode = NULL ;
if ( expr . empty ( ) )
return ;
int atPos = ( int ) expr . IndexOf ( ' @ ' ) ;
if ( ( atPos ! = - 1 ) & & ( atPos < expr . mLength - 2 ) & & ( expr [ atPos + 1 ] = = ' 0 ' ) & & ( expr [ atPos + 2 ] = = ' x ' ) )
{
bool isValid = true ;
for ( int i = 0 ; i < atPos ; i + + )
{
char c = expr [ i ] ;
if ( ( c < ' 0 ' ) | | ( c > ' 9 ' ) )
{
isValid = false ;
break ;
}
}
if ( isValid )
{
int parseLength = expr . mLength ;
for ( int i = 0 ; i < expr . mLength ; i + + )
{
if ( ( expr [ i ] = = ' , ' ) | | ( : : isspace ( ( uint8 ) expr [ i ] ) ) )
{
parseLength = i ;
break ;
}
}
mExprString = expr . Substring ( 0 , parseLength ) ;
String typeIdStr = expr . Substring ( 0 , atPos ) ;
String addrStr = expr . Substring ( atPos + 3 , parseLength - atPos - 3 ) ;
int typeId = strtol ( typeIdStr . c_str ( ) , NULL , 10 ) ;
int64 addrVal = strtoll ( addrStr . c_str ( ) , NULL , 16 ) ;
if ( ( typeId ! = 0 ) & & ( addrVal ! = 0 ) )
{
auto type = ceDebugger - > mCompiler - > mContext - > FindTypeById ( typeId ) ;
if ( type ! = NULL )
{
auto module = ceDebugger - > mCeMachine - > mCeModule ;
if ( type - > IsObjectOrInterface ( ) )
{
mResultOverride = BfTypedValue ( module - > mBfIRBuilder - > CreateIntToPtr (
module - > mBfIRBuilder - > CreateConst ( BfTypeCode_IntPtr , ( uint64 ) addrVal ) , module - > mBfIRBuilder - > MapType ( type ) ) , type ) ;
}
else
{
mResultOverride = BfTypedValue ( module - > mBfIRBuilder - > CreateConstAggCE ( module - > mBfIRBuilder - > MapType ( type ) , ( addr_ce ) addrVal ) , type , true ) ;
}
}
}
return ;
}
}
mParser = new BfParser ( ceDebugger - > mCompiler - > mSystem ) ;
mPassInstance = new BfPassInstance ( ceDebugger - > mCompiler - > mSystem ) ;
auto terminatedExpr = expr + " ; " ;
mParser - > SetSource ( terminatedExpr . c_str ( ) , ( int ) terminatedExpr . length ( ) ) ;
mParser - > Parse ( mPassInstance ) ;
mReducer = new BfReducer ( ) ;
mReducer - > mAlloc = mParser - > mAlloc ;
mReducer - > mSystem = ceDebugger - > mCompiler - > mSystem ;
mReducer - > mPassInstance = mPassInstance ;
mReducer - > mVisitorPos = BfReducer : : BfVisitorPos ( mParser - > mRootNode ) ;
mReducer - > mVisitorPos . MoveNext ( ) ;
mReducer - > mSource = mParser ;
mExprNode = mReducer - > CreateExpression ( mParser - > mRootNode - > GetFirst ( ) ) ;
mParser - > Close ( ) ;
mExprEvaluator = new BfExprEvaluator ( ceDebugger - > mCeMachine - > mCeModule ) ;
if ( ( formatInfo ! = NULL ) & & ( mExprNode ! = NULL ) & & ( mExprNode - > GetSrcEnd ( ) < ( int ) expr . length ( ) ) )
{
String formatFlags = expr . Substring ( mExprNode - > GetSrcEnd ( ) ) ;
String errorString = " Invalid expression " ;
if ( ! ceDebugger - > ParseFormatInfo ( formatFlags , formatInfo , mPassInstance , NULL , NULL , & errorString , contextValue ) )
{
mPassInstance - > FailAt ( errorString , mParser - > mSourceData , mExprNode - > GetSrcEnd ( ) , ( int ) expr . length ( ) - mExprNode - > GetSrcEnd ( ) ) ;
formatFlags = " " ;
}
}
if ( formatInfo ! = NULL )
{
mExplicitThis = formatInfo - > mExplicitThis ;
mCallStackIdx = formatInfo - > mCallStackIdx ;
}
mExprNode - > ToString ( mExprString ) ;
}
bool CeEvaluationContext : : HasExpression ( )
{
return ! mExprString . IsEmpty ( ) ;
}
CeEvaluationContext : : ~ CeEvaluationContext ( )
{
delete mParser ;
delete mReducer ;
delete mExprEvaluator ;
delete mPassInstance ;
}
2022-03-15 16:33:30 -07:00
BfTypedValue CeEvaluationContext : : EvaluateInContext ( BfTypedValue contextTypedValue , CeDbgState * dbgState )
2022-03-08 06:27:06 -08:00
{
if ( mResultOverride )
return mResultOverride ;
if ( mExprNode = = NULL )
return BfTypedValue ( ) ;
mPassInstance - > ClearErrors ( ) ;
auto ceFrame = mDebugger - > GetFrame ( mCallStackIdx ) ;
auto module = mDebugger - > mCeMachine - > mCeModule ;
SetAndRestoreValue < BfTypeInstance * > prevTypeInstance ( module - > mCurTypeInstance , ceFrame - > mFunction - > mMethodInstance - > GetOwner ( ) ) ;
SetAndRestoreValue < BfMethodInstance * > prevMethodInstance ( module - > mCurMethodInstance , ceFrame - > mFunction - > mMethodInstance ) ;
SetAndRestoreValue < BfPassInstance * > prevPassInstance ( mDebugger - > mCompiler - > mPassInstance , mPassInstance ) ;
SetAndRestoreValue < bool > prevIgnoreWrites ( module - > mBfIRBuilder - > mIgnoreWrites , true ) ;
BfMethodState methodState ;
SetAndRestoreValue < BfMethodState * > prevMethodState ( module - > mCurMethodState , & methodState ) ;
methodState . mTempKind = module - > mCurMethodInstance - > mMethodDef - > mIsStatic ? BfMethodState : : TempKind_Static : BfMethodState : : TempKind_NonStatic ;
2022-03-15 16:33:30 -07:00
CeDbgState localDbgState ;
if ( dbgState = = NULL )
dbgState = & localDbgState ;
dbgState - > mActiveFrame = ceFrame ;
dbgState - > mCeContext = mDebugger - > mCeMachine - > mCurContext ;
2022-03-08 06:27:06 -08:00
if ( contextTypedValue )
2022-03-15 16:33:30 -07:00
dbgState - > mExplicitThis = contextTypedValue ;
2022-03-08 06:27:06 -08:00
else
2022-03-15 16:33:30 -07:00
dbgState - > mExplicitThis = mExplicitThis ;
SetAndRestoreValue < CeDbgState * > prevDbgState ( mDebugger - > mCurDbgState , dbgState ) ;
2022-03-08 06:27:06 -08:00
BfTypedValue exprResult ;
mExprEvaluator - > VisitChildNoRef ( mExprNode ) ;
auto result = mExprEvaluator - > mResult ;
if ( ( result ) & & ( ! result . mType - > IsComposite ( ) ) )
result = module - > LoadValue ( result ) ;
return result ;
}
bool CeEvaluationContext : : HadError ( )
{
return ( mPassInstance ! = NULL ) & & ( mPassInstance - > mFailedIdx ! = 0 ) ;
}
String CeEvaluationContext : : GetErrorStr ( )
{
if ( mPassInstance = = NULL )
return " " ;
String errorStr = mPassInstance - > mErrors [ 0 ] - > mError ;
if ( mExprNode ! = NULL )
{
errorStr + = " : " ;
errorStr + = mExprNode - > ToString ( ) ;
}
return errorStr ;
}
//////////////////////////////////////////////////////////////////////////
CeDebugger : : CeDebugger ( DebugManager * debugManager , BfCompiler * bfCompiler )
{
mDebugManager = debugManager ;
mCompiler = bfCompiler ;
2022-03-15 16:33:30 -07:00
mCeMachine = bfCompiler - > mCeMachine ;
2022-03-08 06:27:06 -08:00
mRunState = RunState_Running ;
mCeMachine - > mDebugger = this ;
mCeMachine - > mDebugEvent . Reset ( ) ;
mDebugPendingExpr = NULL ;
mCurDbgState = NULL ;
mBreakpointVersion = 0 ;
mBreakpointCacheDirty = false ;
mBreakpointFramesDirty = false ;
mCurDisasmFuncId = 0 ;
mActiveBreakpoint = NULL ;
mCurEvaluationContext = NULL ;
2022-03-15 16:33:30 -07:00
mPendingActiveFrameOffset = 0 ;
}
String CeDebugger : : TypeToString ( const BfTypedValue & typedValue )
{
if ( typedValue . mType = = NULL )
return " null " ;
if ( typedValue . IsReadOnly ( ) )
return String ( " readonly " ) + mCeMachine - > mCeModule - > TypeToString ( typedValue . mType ) ;
return mCeMachine - > mCeModule - > TypeToString ( typedValue . mType ) ;
}
String CeDebugger : : TypeToString ( BfType * type , CeTypeModKind typeModKind )
{
if ( type = = NULL )
return " null " ;
String str ;
if ( typeModKind = = CeTypeModKind_ReadOnly )
str + = " readonly " ;
else if ( typeModKind = = CeTypeModKind_Const )
str + = " const " ;
str + = mCeMachine - > mCeModule - > TypeToString ( type ) ;
return str ;
2022-03-08 06:27:06 -08:00
}
CeDebugger : : ~ CeDebugger ( )
{
mCeMachine - > mDebugEvent . Set ( true ) ;
mCeMachine - > mDebugger = NULL ;
delete mDebugPendingExpr ;
for ( auto breakpoint : mBreakpoints )
delete breakpoint ;
for ( auto kv : mFileInfo )
delete kv . mValue ;
}
void CeDebugger : : OutputMessage ( const StringImpl & msg )
{
if ( this = = NULL )
return ;
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
mDebugManager - > mOutMessages . push_back ( " msg " + msg ) ;
}
void CeDebugger : : OutputRawMessage ( const StringImpl & msg )
{
if ( this = = NULL )
return ;
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
mDebugManager - > mOutMessages . push_back ( msg ) ;
}
int CeDebugger : : GetAddrSize ( )
{
return sizeof ( addr_ce ) ;
}
bool CeDebugger : : CanOpen ( const StringImpl & fileName , DebuggerResult * outResult )
{
return false ;
}
void CeDebugger : : OpenFile ( const StringImpl & launchPath , const StringImpl & targetPath , const StringImpl & args , const StringImpl & workingDir , const Array < uint8 > & envBlock , bool hotSwapEnabled )
{
}
bool CeDebugger : : Attach ( int processId , BfDbgAttachFlags attachFlags )
{
return false ;
}
void CeDebugger : : Run ( )
{
}
void CeDebugger : : HotLoad ( const Array < String > & objectFiles , int hotIdx )
{
}
void CeDebugger : : InitiateHotResolve ( DbgHotResolveFlags flags )
{
}
intptr CeDebugger : : GetDbgAllocHeapSize ( )
{
return intptr ( ) ;
}
String CeDebugger : : GetDbgAllocInfo ( )
{
return String ( ) ;
}
void CeDebugger : : Update ( )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
2022-03-08 06:27:06 -08:00
if ( ( mRunState = = RunState_Terminated ) | | ( mRunState = = RunState_Terminating ) )
return ;
2022-03-15 16:33:30 -07:00
if ( mDebugPendingExpr ! = NULL )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
if ( mDebugPendingExpr - > mDone )
mRunState = RunState_DebugEval_Done ;
else
mRunState = RunState_DebugEval ;
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
else if ( mCeMachine - > mDbgPaused )
mRunState = RunState_Paused ;
else
mRunState = RunState_Running ;
2022-03-08 06:27:06 -08:00
}
void CeDebugger : : UpdateBreakpointFrames ( )
{
if ( mBreakpointCacheDirty )
UpdateBreakpointCache ( ) ;
for ( auto & callStack : mCeMachine - > mCurContext - > mCallStack )
{
if ( callStack . mFunction - > mBreakpointVersion ! = mBreakpointVersion )
UpdateBreakpoints ( callStack . mFunction ) ;
}
}
void CeDebugger : : ContinueDebugEvent ( )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
2022-03-08 06:27:06 -08:00
mRunState = RunState_Running ;
mActiveBreakpoint = NULL ;
2022-03-15 16:33:30 -07:00
mPendingActiveFrameOffset = 0 ;
mDbgCallStack . Clear ( ) ;
2022-03-08 06:27:06 -08:00
if ( mBreakpointFramesDirty )
UpdateBreakpointFrames ( ) ;
mCeMachine - > mDebugEvent . Set ( ) ;
}
void CeDebugger : : ForegroundTarget ( )
{
}
2022-03-15 16:33:30 -07:00
bool CeDebugger : : CheckConditionalBreakpoint ( CeBreakpoint * breakpoint )
{
auto _SplitExpr = [ & ] ( const StringImpl & expr , StringImpl & outExpr , StringImpl & outSubject )
{
int crPos = ( int ) expr . IndexOf ( ' \n ' ) ;
if ( crPos ! = - 1 )
{
outExpr + = expr . Substring ( 0 , crPos ) ;
outSubject + = expr . Substring ( crPos + 1 ) ;
}
else
{
outExpr + = expr ;
}
} ;
if ( breakpoint - > mCondition ! = NULL )
{
ClearCallStack ( ) ;
auto conditional = breakpoint - > mCondition ;
if ( conditional - > mDbgEvaluationContext = = NULL )
{
StringT < 256 > expr ;
StringT < 256 > subjectExpr ;
_SplitExpr ( conditional - > mExpr , expr , subjectExpr ) ;
conditional - > mDbgEvaluationContext = new CeEvaluationContext ( this , expr ) ;
conditional - > mDbgEvaluationContext - > mCallStackIdx = - 1 ;
}
CeDbgState dbgState ;
BfTypedValue result = conditional - > mDbgEvaluationContext - > EvaluateInContext ( BfTypedValue ( ) , & dbgState ) ;
if ( conditional - > mDbgEvaluationContext - > mPassInstance - > HasFailed ( ) )
{
String errorStr = " FAILED " ;
for ( auto error : conditional - > mDbgEvaluationContext - > mPassInstance - > mErrors )
{
if ( ! error - > mIsWarning )
errorStr = error - > mError ;
}
String condError = StrFormat ( " error Conditional breakpoint expression '%s' failed: %s " , conditional - > mExpr . c_str ( ) , errorStr . c_str ( ) ) ;
mDebugManager - > mOutMessages . push_back ( condError ) ;
return true ;
}
else if ( dbgState . mBlockedSideEffects )
{
mDebugManager - > mOutMessages . push_back ( StrFormat ( " error Conditional breakpoint expression '%s' contained function calls, which is not allowed " , conditional - > mExpr . c_str ( ) ) ) ;
return true ;
}
else if ( ( ! result ) | | ( ! result . mType - > IsBoolean ( ) ) )
{
mDebugManager - > mOutMessages . push_back ( StrFormat ( " error Conditional breakpoint expression '%s' must result in a boolean value " , conditional - > mExpr . c_str ( ) ) ) ;
return true ;
}
else if ( ValueToInt ( result ) < = 0 )
return false ;
}
breakpoint - > mHitCount + + ;
switch ( breakpoint - > mHitCountBreakKind )
{
case DbgHitCountBreakKind_Equals :
if ( breakpoint - > mHitCount ! = breakpoint - > mTargetHitCount )
return false ;
break ;
case DbgHitCountBreakKind_GreaterEquals :
if ( breakpoint - > mHitCount < breakpoint - > mTargetHitCount )
return false ;
break ;
case DbgHitCountBreakKind_Multiple :
if ( ( breakpoint - > mHitCount % breakpoint - > mTargetHitCount ) ! = 0 )
return false ;
break ;
}
if ( ! breakpoint - > mLogging . IsEmpty ( ) )
{
auto ceContext = mCeMachine - > mCurContext ;
CeDbgState dbgState ;
dbgState . mActiveFrame = & ceContext - > mCallStack [ 0 ] ;
dbgState . mCeContext = mCeMachine - > mCurContext ;
SetAndRestoreValue < CeDbgState * > prevDbgState ( mCurDbgState , & dbgState ) ;
ClearCallStack ( ) ;
CeFormatInfo formatInfo ;
formatInfo . mCallStackIdx = - 1 ;
auto prevRunState = mRunState ;
mRunState = RunState_Paused ; // We need to be paused to avoid certain errors in the eval
String displayString ;
String expr ;
_SplitExpr ( breakpoint - > mLogging , expr , formatInfo . mSubjectExpr ) ;
ProcessEvalString ( BfTypedValue ( ) , expr , displayString , formatInfo , NULL , false ) ;
mRunState = prevRunState ;
displayString . Insert ( 0 , " log " ) ;
displayString . Append ( " \n " ) ;
mDebugManager - > mOutMessages . push_back ( displayString ) ;
if ( ! breakpoint - > mBreakAfterLogging )
return false ;
}
return true ;
}
2022-03-08 06:27:06 -08:00
Breakpoint * CeDebugger : : CreateBreakpoint ( const StringImpl & fileName , int lineNum , int wantColumn , int instrOffset )
{
ClearBreakpointCache ( ) ;
auto breakpoint = new CeBreakpoint ( ) ;
breakpoint - > mFilePath = fileName ;
breakpoint - > mRequestedLineNum = lineNum ;
breakpoint - > mLineNum = lineNum ;
breakpoint - > mColumn = wantColumn ;
breakpoint - > mInstrOffset = instrOffset ;
mBreakpoints . Add ( breakpoint ) ;
mBreakpointVersion + + ;
return breakpoint ;
}
Breakpoint * CeDebugger : : CreateMemoryBreakpoint ( intptr addr , int byteCount )
{
return nullptr ;
}
Breakpoint * CeDebugger : : CreateSymbolBreakpoint ( const StringImpl & symbolName )
{
return nullptr ;
}
Breakpoint * CeDebugger : : CreateAddressBreakpoint ( intptr address )
{
return nullptr ;
}
uintptr CeDebugger : : GetBreakpointAddr ( Breakpoint * breakpoint )
{
if ( mBreakpointCacheDirty )
{
UpdateBreakpointCache ( ) ;
UpdateBreakpointAddrs ( ) ;
}
return breakpoint - > GetAddr ( ) ;
}
void CeDebugger : : CheckBreakpoint ( Breakpoint * breakpoint )
{
}
void CeDebugger : : HotBindBreakpoint ( Breakpoint * breakpoint , int lineNum , int hotIdx )
{
2022-03-15 16:33:30 -07:00
}
int64 CeDebugger : : ValueToInt ( addr_ce addr , BfType * type )
{
if ( ( ! type - > IsInteger ( ) ) & & ( ! type - > IsBoolean ( ) ) )
return 0 ;
auto primType = ( BfPrimitiveType * ) type ;
auto ceContext = mCeMachine - > mCurContext ;
int64 val = 0 ;
memcpy ( & val , ceContext - > mMemory . mVals + addr , type - > mSize ) ;
switch ( primType - > mTypeDef - > mTypeCode )
{
case BfTypeCode_Int8 :
val = * ( int8 * ) & val ;
break ;
case BfTypeCode_Int16 :
val = * ( int16 * ) & val ;
break ;
case BfTypeCode_Int32 :
val = * ( int32 * ) & val ;
break ;
}
return val ;
2022-03-08 06:27:06 -08:00
}
int64 CeDebugger : : ValueToInt ( const BfTypedValue & typedVal )
{
2022-03-15 16:33:30 -07:00
auto ceModule = mCeMachine - > mCeModule ;
auto constant = ceModule - > mBfIRBuilder - > GetConstant ( typedVal . mValue ) ;
2022-03-08 06:27:06 -08:00
if ( constant = = NULL )
return 0 ;
if ( typedVal . IsAddr ( ) )
{
BfType * type = typedVal . mType ;
if ( type - > IsTypedPrimitive ( ) )
type = type - > GetUnderlyingType ( ) ;
if ( ( type - > IsInteger ( ) ) | | ( type - > IsBoolean ( ) ) )
2022-03-15 16:33:30 -07:00
{
2022-03-08 06:27:06 -08:00
auto ceTypedVal = GetAddr ( constant ) ;
if ( ceTypedVal )
2022-03-15 16:33:30 -07:00
return ValueToInt ( ( addr_ce ) ceTypedVal . mAddr , type ) ;
2022-03-08 06:27:06 -08:00
}
return 0 ;
2022-03-15 16:33:30 -07:00
}
if ( constant - > mConstType = = BfConstType_ExtractValue )
{
auto fromConstGEP = ( BfConstantExtractValue * ) constant ;
auto fromTarget = ceModule - > mBfIRBuilder - > GetConstantById ( fromConstGEP - > mTarget ) ;
if ( fromTarget - > mConstType = = BfConstType_AggCE )
{
auto aggCE = ( BfConstantAggCE * ) fromTarget ;
auto dbgTypeInfo = GetDbgTypeInfo ( aggCE - > mType ) ;
if ( dbgTypeInfo = = NULL )
return 0 ;
auto typeInst = dbgTypeInfo - > mType - > ToTypeInstance ( ) ;
if ( typeInst = = NULL )
return 0 ;
auto fieldInfo = & dbgTypeInfo - > mFieldOffsets [ fromConstGEP - > mIdx0 ] ;
return ValueToInt ( aggCE - > mCEAddr + fieldInfo - > mDataOffset , fieldInfo - > mType ) ;
}
}
2022-03-08 06:27:06 -08:00
if ( ( BfIRConstHolder : : IsInt ( constant - > mTypeCode ) ) | | ( constant - > mTypeCode = = BfTypeCode_Boolean ) )
return constant - > mInt64 ;
return 0 ;
}
void CeDebugger : : DeleteBreakpoint ( Breakpoint * breakpoint )
{
if ( mActiveBreakpoint = = breakpoint )
mActiveBreakpoint = NULL ;
mBreakpoints . Remove ( ( CeBreakpoint * ) breakpoint ) ;
delete breakpoint ;
ClearBreakpointCache ( ) ;
}
void CeDebugger : : DetachBreakpoint ( Breakpoint * breakpoint )
{
}
void CeDebugger : : MoveBreakpoint ( Breakpoint * breakpoint , int lineNum , int wantColumn , bool rebindNow )
{
breakpoint - > mLineNum = lineNum ;
breakpoint - > mColumn = wantColumn ;
ClearBreakpointCache ( ) ;
}
void CeDebugger : : MoveMemoryBreakpoint ( Breakpoint * breakpoint , intptr addr , int byteCount )
{
}
void CeDebugger : : DisableBreakpoint ( Breakpoint * breakpoint )
{
}
2022-03-15 16:33:30 -07:00
void CeDebugger : : SetBreakpointCondition ( Breakpoint * breakpoint , const StringImpl & conditionExpr )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
CeBreakpoint * wdBreakpoint = ( CeBreakpoint * ) breakpoint ;
BF_ASSERT ( ! wdBreakpoint - > mIsLinkedSibling ) ;
if ( conditionExpr . empty ( ) )
{
delete wdBreakpoint - > mCondition ;
CeBreakpoint * curBreakpoint = wdBreakpoint ;
wdBreakpoint - > mCondition = NULL ;
}
else
{
delete wdBreakpoint - > mCondition ;
auto condition = new CeBreakpointCondition ( ) ;
condition - > mExpr = conditionExpr ;
wdBreakpoint - > mCondition = condition ;
}
2022-03-08 06:27:06 -08:00
}
void CeDebugger : : SetBreakpointLogging ( Breakpoint * breakpoint , const StringImpl & logging , bool breakAfterLogging )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
CeBreakpoint * wdBreakpoint = ( CeBreakpoint * ) breakpoint ;
BF_ASSERT ( ! wdBreakpoint - > mIsLinkedSibling ) ;
wdBreakpoint - > mLogging = logging ;
wdBreakpoint - > mBreakAfterLogging = breakAfterLogging ;
2022-03-08 06:27:06 -08:00
}
Breakpoint * CeDebugger : : FindBreakpointAt ( intptr address )
{
return nullptr ;
}
Breakpoint * CeDebugger : : GetActiveBreakpoint ( )
{
return mActiveBreakpoint ;
}
void CeDebugger : : BreakAll ( )
{
mCeMachine - > mSpecialCheck = true ;
mCeMachine - > mDbgWantBreak = true ;
}
bool CeDebugger : : TryRunContinue ( )
{
return false ;
}
bool CeDebugger : : SetupStep ( int frameIdx )
{
auto ceFrame = GetFrame ( frameIdx ) ;
if ( ceFrame = = NULL )
{
ContinueDebugEvent ( ) ;
return false ;
}
int entryIdx = 0 ;
auto curEntry = ceFrame - > mFunction - > FindEmitEntry ( ceFrame - > GetInstIdx ( ) , & entryIdx ) ;
if ( curEntry = = NULL )
{
ContinueDebugEvent ( ) ;
return false ;
}
auto ceMachine = mCeMachine ;
auto ceContext = mCeMachine - > mCurContext ;
if ( entryIdx < ceFrame - > mFunction - > mEmitTable . mSize - 1 )
{
int checkIdx = entryIdx + 1 ;
while ( checkIdx < ceFrame - > mFunction - > mEmitTable . mSize )
{
auto checkEntry = & ceFrame - > mFunction - > mEmitTable [ checkIdx ] ;
ceMachine - > mStepState . mNextInstIdx = checkEntry - > mCodePos ;
if ( ( checkEntry - > mScope ! = curEntry - > mScope ) | | ( checkEntry - > mLine ! = curEntry - > mLine ) )
break ;
+ + checkIdx ;
}
}
else
ceMachine - > mStepState . mNextInstIdx = ceFrame - > mFunction - > mCode . mSize ;
ceMachine - > mStepState . mStartDepth = ceContext - > mCallStack . mSize - frameIdx ;
ceMachine - > mSpecialCheck = true ;
ContinueDebugEvent ( ) ;
return true ;
}
void CeDebugger : : StepInto ( bool inAssembly )
{
if ( ! SetupStep ( ) )
return ;
mCeMachine - > mStepState . mKind = inAssembly ? CeStepState : : Kind_StepInfo_Asm : CeStepState : : Kind_StepInfo ;
}
void CeDebugger : : StepIntoSpecific ( intptr addr )
{
}
void CeDebugger : : StepOver ( bool inAssembly )
{
if ( ! SetupStep ( ) )
return ;
mCeMachine - > mStepState . mKind = inAssembly ? CeStepState : : Kind_StepOver_Asm : CeStepState : : Kind_StepOver ;
}
void CeDebugger : : StepOut ( bool inAssembly )
{
if ( ! SetupStep ( 1 ) )
return ;
mCeMachine - > mStepState . mKind = inAssembly ? CeStepState : : Kind_StepOut_Asm : CeStepState : : Kind_StepOut ;
}
void CeDebugger : : SetNextStatement ( bool inAssembly , const StringImpl & fileName , int64 lineNumOrAsmAddr , int wantColumn )
{
auto ceFrame = GetFrame ( 0 ) ;
if ( ceFrame = = NULL )
return ;
if ( inAssembly )
{
int32 instIdx = ( int32 ) lineNumOrAsmAddr ;
if ( instIdx < ceFrame - > mFunction - > mCode . mSize )
{
mCeMachine - > mSpecialCheck = true ;
mCeMachine - > mStepState . mKind = CeStepState : : Kind_Jmp ;
mCeMachine - > mStepState . mNextInstIdx = instIdx ;
ContinueDebugEvent ( ) ;
}
}
else
{
for ( auto & emitEntry : ceFrame - > mFunction - > mEmitTable )
{
if ( emitEntry . mScope = = - 1 )
continue ;
auto & scope = ceFrame - > mFunction - > mDbgScopes [ emitEntry . mScope ] ;
if ( ( FileNameEquals ( fileName , scope . mFilePath ) & & ( emitEntry . mLine = = lineNumOrAsmAddr ) ) )
{
mCeMachine - > mSpecialCheck = true ;
mCeMachine - > mStepState . mKind = CeStepState : : Kind_Jmp ;
mCeMachine - > mStepState . mNextInstIdx = emitEntry . mCodePos ;
ContinueDebugEvent ( ) ;
return ;
}
}
}
}
CeFrame * CeDebugger : : GetFrame ( int callStackIdx )
2022-03-17 08:47:34 -07:00
{
2022-03-08 06:27:06 -08:00
auto ceContext = mCeMachine - > mCurContext ;
if ( ceContext = = NULL )
return NULL ;
2022-03-15 16:33:30 -07:00
if ( ( callStackIdx = = - 1 ) & & ( ! ceContext - > mCallStack . IsEmpty ( ) ) )
return & ceContext - > mCallStack . back ( ) ;
if ( callStackIdx < mDbgCallStack . mSize )
2022-03-08 06:27:06 -08:00
{
2022-03-17 08:47:34 -07:00
int frameIdx = mDbgCallStack [ callStackIdx ] . mFrameIdx ;
if ( frameIdx < 0 )
return NULL ;
2022-03-15 16:33:30 -07:00
auto ceFrame = & ceContext - > mCallStack [ mDbgCallStack [ callStackIdx ] . mFrameIdx ] ;
2022-03-08 06:27:06 -08:00
return ceFrame ;
}
return NULL ;
}
2022-03-15 16:33:30 -07:00
String CeDebugger : : GetAutocompleteOutput ( BfAutoComplete & autoComplete )
{
String val = " \n :autocomplete \n " ;
if ( autoComplete . mInsertStartIdx ! = - 1 )
{
val + = StrFormat ( " insertRange \t %d %d \n " , autoComplete . mInsertStartIdx , autoComplete . mInsertEndIdx ) ;
}
Array < AutoCompleteEntry * > entries ;
for ( auto & entry : autoComplete . mEntriesSet )
{
entries . Add ( & entry ) ;
}
std : : sort ( entries . begin ( ) , entries . end ( ) , [ ] ( AutoCompleteEntry * lhs , AutoCompleteEntry * rhs )
{
return stricmp ( lhs - > mDisplay , rhs - > mDisplay ) < 0 ;
} ) ;
for ( auto entry : entries )
{
val + = String ( entry - > mEntryType ) ;
val + = " \t " ;
val + = String ( entry - > mDisplay ) ;
val + = " \n " ;
}
/*if (autoComplete.mEntries.size() != 0)
{
for ( auto & entry : autoComplete . mEntries )
{
val + = String ( entry . mEntryType ) + " \t " + String ( entry . mDisplay ) + " \n " ;
}
} */
return val ;
}
String CeDebugger : : DoEvaluate ( CePendingExpr * pendingExpr , bool inCompilerThread )
2022-03-08 06:27:06 -08:00
{
auto ceFrame = GetFrame ( pendingExpr - > mCallStackIdx ) ;
if ( ceFrame = = NULL )
{
2022-03-17 08:47:34 -07:00
return " !No comptime stack frame selected " ;
2022-03-08 06:27:06 -08:00
}
if ( pendingExpr - > mExprNode = = NULL )
{
2022-03-17 08:47:34 -07:00
return " !No expression " ;
2022-03-08 06:27:06 -08:00
}
auto module = mCeMachine - > mCeModule ;
2022-03-15 16:33:30 -07:00
if ( ! mCeMachine - > mDbgPaused )
pendingExpr - > mPassInstance - > ClearErrors ( ) ;
SetAndRestoreValue < BfTypeState * > prevTypeState ( module - > mContext - > mCurTypeState , NULL ) ;
SetAndRestoreValue < BfConstraintState * > prevConstraintState ( module - > mContext - > mCurConstraintState , NULL ) ;
2022-03-08 06:27:06 -08:00
SetAndRestoreValue < BfTypeInstance * > prevTypeInstance ( module - > mCurTypeInstance , ceFrame - > mFunction - > mMethodInstance - > GetOwner ( ) ) ;
SetAndRestoreValue < BfMethodInstance * > prevMethodInstance ( module - > mCurMethodInstance , ceFrame - > mFunction - > mMethodInstance ) ;
2022-03-15 16:33:30 -07:00
SetAndRestoreValue < BfPassInstance * > prevPassInstance ( mCompiler - > mPassInstance , pendingExpr - > mPassInstance ) ;
2022-03-08 06:27:06 -08:00
SetAndRestoreValue < bool > prevIgnoreWrites ( module - > mBfIRBuilder - > mIgnoreWrites , true ) ;
BfMethodState methodState ;
SetAndRestoreValue < BfMethodState * > prevMethodState ( module - > mCurMethodState , & methodState ) ;
methodState . mTempKind = module - > mCurMethodInstance - > mMethodDef - > mIsStatic ? BfMethodState : : TempKind_Static : BfMethodState : : TempKind_NonStatic ;
CeDbgState dbgState ;
dbgState . mActiveFrame = ceFrame ;
dbgState . mCeContext = mCeMachine - > mCurContext ;
dbgState . mExplicitThis = pendingExpr - > mFormatInfo . mExplicitThis ;
dbgState . mDbgExpressionFlags = pendingExpr - > mExpressionFlags ;
2022-03-15 16:33:30 -07:00
if ( ! inCompilerThread )
dbgState . mDbgExpressionFlags = ( DwEvalExpressionFlags ) ( dbgState . mDbgExpressionFlags & ~ ( DwEvalExpressionFlag_AllowCalls | DwEvalExpressionFlag_AllowPropertyEval ) ) ;
dbgState . mFormatInfo = & pendingExpr - > mFormatInfo ;
2022-03-08 06:27:06 -08:00
SetAndRestoreValue < CeDbgState * > prevDbgState ( mCurDbgState , & dbgState ) ;
2022-03-15 16:33:30 -07:00
BfAutoComplete autoComplete ;
autoComplete . mModule = module ;
autoComplete . mCompiler = module - > mCompiler ;
autoComplete . mSystem = module - > mSystem ;
BfResolvePassData resolvePass ;
2022-04-16 06:27:54 -07:00
resolvePass . mParsers . Add ( pendingExpr - > mParser ) ;
2022-03-15 16:33:30 -07:00
resolvePass . mAutoComplete = & autoComplete ;
SetAndRestoreValue < BfResolvePassData * > prevResolvePass ;
if ( pendingExpr - > mCursorPos ! = - 1 )
{
pendingExpr - > mParser - > mParserFlags = ( BfParserFlag ) ( pendingExpr - > mParser - > mParserFlags | ParserFlag_Autocomplete ) ;
pendingExpr - > mParser - > mCursorIdx = pendingExpr - > mCursorPos + 1 ;
pendingExpr - > mParser - > mCursorCheckIdx = pendingExpr - > mCursorPos + 1 ;
prevResolvePass . Init ( module - > mCompiler - > mResolvePassData , & resolvePass ) ;
}
2022-03-08 06:27:06 -08:00
BfTypedValue exprResult ;
2022-03-15 16:33:30 -07:00
BfTypedValue origExprResult ;
2022-03-08 06:27:06 -08:00
if ( auto typeRef = BfNodeDynCast < BfTypeReference > ( pendingExpr - > mExprNode ) )
{
auto resultType = mCeMachine - > mCeModule - > ResolveTypeRef ( typeRef ) ;
if ( resultType ! = NULL )
exprResult = BfTypedValue ( resultType ) ;
}
else
{
BfExprEvaluator exprEvaluator ( mCeMachine - > mCeModule ) ;
exprEvaluator . mBfEvalExprFlags = ( BfEvalExprFlags ) ( exprEvaluator . mBfEvalExprFlags | BfEvalExprFlags_Comptime ) ;
2022-03-15 16:33:30 -07:00
exprEvaluator . VisitChildNoRef ( pendingExpr - > mExprNode ) ;
exprResult = exprEvaluator . GetResult ( ) ;
origExprResult = exprResult ;
2022-03-08 06:27:06 -08:00
if ( ( exprResult ) & & ( ! exprResult . mType - > IsComposite ( ) ) )
exprResult = module - > LoadValue ( exprResult ) ;
2022-03-15 16:33:30 -07:00
module - > FixIntUnknown ( exprResult ) ;
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
2022-03-08 06:27:06 -08:00
if ( dbgState . mBlockedSideEffects )
2022-03-15 16:33:30 -07:00
{
if ( ( mCeMachine - > mDbgPaused ) & & ( ( pendingExpr - > mExpressionFlags & DwEvalExpressionFlag_AllowCalls ) ! = 0 ) )
{
// Reprocess in compiler thread
return " !pending " ;
}
2022-03-08 06:27:06 -08:00
return " !sideeffects " ;
2022-03-15 16:33:30 -07:00
}
2022-03-08 06:27:06 -08:00
if ( ! exprResult )
{
auto resultType = mCeMachine - > mCeModule - > ResolveTypeRef ( pendingExpr - > mExprNode , { } , BfPopulateType_Data , BfResolveTypeRefFlag_IgnoreLookupError ) ;
if ( resultType ! = NULL )
{
exprResult = BfTypedValue ( resultType ) ;
2022-03-15 16:33:30 -07:00
pendingExpr - > mPassInstance - > ClearErrors ( ) ;
}
}
if ( ( exprResult . mType = = NULL ) & & ( dbgState . mReferencedIncompleteTypes ) )
{
if ( ( mCeMachine - > mDbgPaused ) & & ( ( pendingExpr - > mExpressionFlags & DwEvalExpressionFlag_AllowCalls ) ! = 0 ) )
{
// Reprocess in compiler thread
return " !pending " ;
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
return " !incomplete " ;
2022-03-08 06:27:06 -08:00
}
String val ;
2022-03-15 16:33:30 -07:00
if ( pendingExpr - > mPassInstance - > HasFailed ( ) )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
BfLogDbgExpr ( " Evaluate Failed: %s \n " , pendingExpr - > mPassInstance - > mErrors [ 0 ] - > mError . c_str ( ) ) ;
String errorStr = pendingExpr - > mPassInstance - > mErrors [ 0 ] - > mError ;
for ( auto moreInfo : pendingExpr - > mPassInstance - > mErrors [ 0 ] - > mMoreInfo )
{
errorStr + = " " ;
errorStr + = moreInfo - > mInfo ;
}
errorStr . Replace ( ' \n ' , ' ' ) ;
val = StrFormat ( " !%d \t %d \t %s " , pendingExpr - > mPassInstance - > mErrors [ 0 ] - > GetSrcStart ( ) , pendingExpr - > mPassInstance - > mErrors [ 0 ] - > GetSrcLength ( ) , errorStr . c_str ( ) ) ;
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
else if ( ( ! exprResult ) & & ( ! exprResult . IsNoValueType ( ) ) )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
return " !Debug evaluate failed " ;
}
else
{
CeTypeModKind typeModKind = CeTypeModKind_Normal ;
if ( ( origExprResult ) & & ( ! origExprResult . IsAddr ( ) ) & & ( origExprResult . mType - > IsValueType ( ) ) )
typeModKind = CeTypeModKind_Const ;
else if ( origExprResult . IsReadOnly ( ) )
typeModKind = CeTypeModKind_ReadOnly ;
val = TypedValueToString ( exprResult , pendingExpr - > mExprNode - > ToString ( ) , pendingExpr - > mFormatInfo , ( pendingExpr - > mExpressionFlags & DwEvalExpressionFlag_FullPrecision ) ! = 0 , typeModKind ) ;
2022-03-08 06:27:06 -08:00
if ( ( ! val . empty ( ) ) & & ( val [ 0 ] = = ' ! ' ) )
return val ;
if ( pendingExpr - > mFormatInfo . mRawString )
return val ;
2022-03-15 16:33:30 -07:00
if ( pendingExpr - > mPassInstance - > HasMessages ( ) )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
for ( auto error : pendingExpr - > mPassInstance - > mErrors )
2022-03-08 06:27:06 -08:00
{
if ( error - > mIsWarning )
{
val + = " \n :warn \t " ;
val + = error - > mError ;
}
}
}
if ( ! pendingExpr - > mFormatInfo . mReferenceId . empty ( ) )
val + = " \n :referenceId \t " + pendingExpr - > mFormatInfo . mReferenceId ;
// if ((exprResult.mSrcAddress != 0) && (HasMemoryBreakpoint(exprResult.mSrcAddress, exprResult.mType->GetByteCount())))
// val += StrFormat("\n:break\t%@", exprResult.mSrcAddress);
auto checkType = exprResult . mType ;
if ( checkType - > IsObject ( ) )
val + = " \n :type \t object " ;
else if ( checkType - > IsPointer ( ) )
val + = " \n :type \t pointer " ;
else if ( checkType - > IsInteger ( ) )
val + = " \n :type \t int " ;
else if ( checkType - > IsFloat ( ) )
val + = " \n :type \t float " ;
}
if ( dbgState . mHadSideEffects )
val + = " \n :sideeffects " ;
2022-03-15 16:33:30 -07:00
// auto resultConstant = module->mBfIRBuilder->GetConstant(exprResult.mValue);
// if (resultConstant != NULL)
// {
// auto ceResultTyped = GetAddr(resultConstant);
// if (ceResultTyped.mAddr != 0)
// val += "\n:canEdit";
// }
if ( ( origExprResult . mType ! = NULL ) & & ( ! origExprResult . mType - > IsComposite ( ) ) & & ( ! origExprResult . mType - > IsRef ( ) ) & &
( origExprResult . IsAddr ( ) ) & & ( ! origExprResult . IsReadOnly ( ) ) )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
val + = " \n :canEdit " ;
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
if ( pendingExpr - > mCursorPos ! = - 1 )
val + = GetAutocompleteOutput ( autoComplete ) ;
2022-03-08 06:27:06 -08:00
return val ;
}
String CeDebugger : : Evaluate ( const StringImpl & expr , CeFormatInfo formatInfo , int callStackIdx , int cursorPos , int language , DwEvalExpressionFlags expressionFlags )
{
BP_ZONE_F ( " WinDebugger::Evaluate %s " , BP_DYN_STR ( expr . c_str ( ) ) ) ;
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
if ( ( expressionFlags & DwEvalExpressionFlag_RawStr ) ! = 0 )
{
formatInfo . mRawString = true ;
}
2022-03-15 16:33:30 -07:00
auto ceContext = mCeMachine - > mCurContext ;
2022-03-08 06:27:06 -08:00
bool valIsAddr = false ;
BfParser * parser = new BfParser ( mCompiler - > mSystem ) ;
2022-03-15 16:33:30 -07:00
BfPassInstance * bfPassInstance = new BfPassInstance ( mCompiler - > mSystem ) ;
2022-03-08 06:27:06 -08:00
auto parseAsType = false ;
auto terminatedExpr = expr ;
terminatedExpr . Trim ( ) ;
if ( terminatedExpr . EndsWith ( " > " ) )
parseAsType = true ;
else if ( ( terminatedExpr . StartsWith ( " comptype( " ) ) & & ( ! terminatedExpr . Contains ( ' . ' ) ) )
parseAsType = true ;
if ( ! parseAsType )
terminatedExpr + = " ; " ;
if ( ( terminatedExpr . length ( ) > 2 ) & & ( terminatedExpr [ 0 ] = = ' @ ' ) )
{
if ( terminatedExpr [ 1 ] = = ' ! ' ) // Return string as error
{
int errorEnd = ( int ) terminatedExpr . IndexOf ( " @! " , 2 ) ;
if ( errorEnd ! = - 1 )
return terminatedExpr . Substring ( 1 , errorEnd - 1 ) ;
else
return terminatedExpr . Substring ( 1 ) ;
}
else if ( terminatedExpr [ 1 ] = = ' > ' ) // Return string as text
{
int errorEnd = ( int ) terminatedExpr . IndexOf ( " @> " , 2 ) ;
if ( errorEnd ! = - 1 )
return terminatedExpr . Substring ( 2 , errorEnd - 1 ) ;
else
return terminatedExpr . Substring ( 2 ) ;
}
}
parser - > SetSource ( terminatedExpr . c_str ( ) , ( int ) terminatedExpr . length ( ) ) ;
2022-03-15 16:33:30 -07:00
parser - > Parse ( bfPassInstance ) ;
2022-03-08 06:27:06 -08:00
BfReducer bfReducer ;
bfReducer . mAlloc = parser - > mAlloc ;
bfReducer . mSystem = mCompiler - > mSystem ;
2022-03-15 16:33:30 -07:00
bfReducer . mPassInstance = bfPassInstance ;
2022-03-08 06:27:06 -08:00
bfReducer . mVisitorPos = BfReducer : : BfVisitorPos ( parser - > mRootNode ) ;
bfReducer . mVisitorPos . MoveNext ( ) ;
bfReducer . mSource = parser ;
BfAstNode * exprNode = NULL ;
if ( parseAsType )
exprNode = bfReducer . CreateTypeRef ( parser - > mRootNode - > mChildArr . GetAs < BfAstNode * > ( 0 ) ) ;
else
exprNode = bfReducer . CreateExpression ( parser - > mRootNode - > mChildArr . GetAs < BfAstNode * > ( 0 ) ) ;
parser - > Close ( ) ;
formatInfo . mCallStackIdx = callStackIdx ;
CePendingExpr * pendingExpr = new CePendingExpr ( ) ;
2022-03-15 16:33:30 -07:00
pendingExpr - > mPassInstance = bfPassInstance ;
2022-03-08 06:27:06 -08:00
pendingExpr - > mParser = parser ;
pendingExpr - > mCallStackIdx = callStackIdx ;
pendingExpr - > mCursorPos = cursorPos ;
pendingExpr - > mExpressionFlags = expressionFlags ;
pendingExpr - > mExprNode = exprNode ;
BfType * explicitType = NULL ;
String formatFlags ;
String assignExpr ;
int assignExprOffset = - 1 ;
if ( ( exprNode ! = NULL ) & & ( exprNode - > GetSrcEnd ( ) < ( int ) expr . length ( ) ) )
{
int formatOffset = exprNode - > GetSrcEnd ( ) ;
while ( formatOffset < ( int ) expr . length ( ) )
{
char c = expr [ formatOffset ] ;
if ( c = = ' ' )
formatOffset + + ;
else
break ;
}
formatFlags = Trim ( expr . Substring ( formatOffset ) ) ;
bool isComplexType = false ;
for ( char c : formatFlags )
if ( c = = ' > ' )
isComplexType = true ;
if ( isComplexType )
{
//explicitType = dbgModule->FindType(expr);
}
if ( ( explicitType = = NULL ) & & ( formatFlags . length ( ) > 0 ) )
{
String errorString = " Invalid expression " ;
2022-03-15 16:33:30 -07:00
if ( ! ParseFormatInfo ( formatFlags , & formatInfo , bfPassInstance , & assignExprOffset , & assignExpr , & errorString ) )
2022-03-08 06:27:06 -08:00
{
if ( formatInfo . mRawString )
return " " ;
2022-03-15 16:33:30 -07:00
bfPassInstance - > FailAt ( errorString , parser - > mSourceData , exprNode - > GetSrcEnd ( ) , ( int ) expr . length ( ) - exprNode - > GetSrcEnd ( ) ) ;
2022-03-08 06:27:06 -08:00
formatFlags = " " ;
}
if ( assignExprOffset ! = - 1 )
assignExprOffset + = formatOffset ;
}
}
if ( assignExpr . length ( ) > 0 )
{
String newEvalStr = exprNode - > ToString ( ) + " = " ;
int errorOffset = ( int ) newEvalStr . length ( ) ;
newEvalStr + = assignExpr ;
String result = Evaluate ( newEvalStr , formatInfo , callStackIdx , cursorPos , language , expressionFlags ) ;
if ( result [ 0 ] = = ' ! ' )
{
int tabPos = ( int ) result . IndexOf ( ' \t ' ) ;
if ( tabPos > 0 )
{
int errorStart = atoi ( result . Substring ( 1 , tabPos - 1 ) . c_str ( ) ) ;
if ( errorStart > = errorOffset )
{
result = StrFormat ( " !%d " , errorStart - errorOffset + assignExprOffset ) + result . Substring ( tabPos ) ;
}
}
}
return result ;
}
pendingExpr - > mExplitType = explicitType ;
pendingExpr - > mFormatInfo = formatInfo ;
2022-03-15 16:33:30 -07:00
String result = DoEvaluate ( pendingExpr , false ) ;
2022-03-08 06:27:06 -08:00
if ( result = = " !pending " )
{
BF_ASSERT ( mDebugPendingExpr = = NULL ) ;
if ( mDebugPendingExpr ! = NULL )
{
return " !retry " ; // We already have a pending
}
mDebugPendingExpr = pendingExpr ;
2022-03-15 16:33:30 -07:00
mCeMachine - > mStepState . mKind = CeStepState : : Kind_Evaluate ;
mRunState = RunState_DebugEval ;
ContinueDebugEvent ( ) ;
2022-03-08 06:27:06 -08:00
}
else
delete pendingExpr ;
return result ;
}
void CeDebugger : : ClearBreakpointCache ( )
{
if ( ! mCeMachine - > mDbgPaused )
mCeMachine - > mSpecialCheck = true ;
mBreakpointFramesDirty = true ;
mBreakpointCacheDirty = true ;
for ( auto kv : mFileInfo )
delete kv . mValue ;
mFileInfo . Clear ( ) ;
}
void CeDebugger : : UpdateBreakpointAddrs ( )
{
for ( auto breakpoint : mBreakpoints )
{
breakpoint - > mCurBindAddr = 1 ;
}
CeFunction * ceFunction = NULL ;
if ( ! mCeMachine - > mFunctionIdMap . TryGetValue ( mCurDisasmFuncId , & ceFunction ) )
return ;
if ( ceFunction - > mBreakpointVersion ! = mBreakpointVersion )
UpdateBreakpoints ( ceFunction ) ;
for ( auto kv : ceFunction - > mBreakpoints )
kv . mValue . mBreakpoint - > mCurBindAddr = ( ( intptr ) ceFunction - > mId < < 32 ) | kv . mKey ;
}
void CeDebugger : : UpdateBreakpointCache ( )
{
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
mBreakpointCacheDirty = false ;
if ( ! mFileInfo . IsEmpty ( ) )
return ;
for ( int i = 0 ; i < ( int ) mBreakpoints . mSize ; i + + )
{
auto breakpoint = mBreakpoints [ i ] ;
breakpoint - > mIdx = i ;
String fileName = breakpoint - > mFilePath ;
fileName = FixPathAndCase ( fileName ) ;
CeFileInfo * * valuePtr ;
CeFileInfo * fileInfo = NULL ;
if ( mFileInfo . TryAdd ( fileName , NULL , & valuePtr ) )
{
fileInfo = new CeFileInfo ( ) ;
* valuePtr = fileInfo ;
}
else
fileInfo = * valuePtr ;
fileInfo - > mOrderedBreakpoints . Add ( breakpoint ) ;
}
for ( auto kv : mFileInfo )
{
kv . mValue - > mOrderedBreakpoints . Sort ( [ ] ( CeBreakpoint * lhs , CeBreakpoint * rhs )
{
return lhs - > mLineNum < rhs - > mLineNum ;
} ) ;
}
}
static int CompareBreakpoint ( CeBreakpoint * breakpoint , const int & lineNum )
{
return breakpoint - > mRequestedLineNum - lineNum ;
}
void CeDebugger : : UpdateBreakpoints ( CeFunction * ceFunction )
{
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
UpdateBreakpointCache ( ) ;
ceFunction - > UnbindBreakpoints ( ) ;
String path ;
int scope = - 1 ;
CeFileInfo * ceFileInfo = NULL ;
BitSet usedBreakpointSet ( mBreakpoints . mSize ) ;
for ( auto & emitEntry : ceFunction - > mEmitTable )
{
if ( emitEntry . mScope ! = scope )
{
if ( emitEntry . mScope ! = - 1 )
{
path = FixPathAndCase ( ceFunction - > mDbgScopes [ emitEntry . mScope ] . mFilePath ) ;
if ( ! mFileInfo . TryGetValue ( path , & ceFileInfo ) )
ceFileInfo = NULL ;
}
else
ceFileInfo = NULL ;
scope = emitEntry . mScope ;
}
if ( ceFileInfo ! = NULL )
{
int idx = ceFileInfo - > mOrderedBreakpoints . BinarySearchAlt < int > ( emitEntry . mLine , CompareBreakpoint ) ;
if ( idx < 0 )
idx = ~ idx - 1 ;
while ( idx > 0 )
{
auto breakpoint = ceFileInfo - > mOrderedBreakpoints [ idx - 1 ] ;
if ( breakpoint - > mLineNum < emitEntry . mLine )
break ;
idx - - ;
}
int tryBindCount = 0 ;
int bestRequestedBindLine = 0 ;
while ( ( idx > = 0 ) & & ( idx < ceFileInfo - > mOrderedBreakpoints . mSize ) )
{
auto breakpoint = ceFileInfo - > mOrderedBreakpoints [ idx ] ;
if ( usedBreakpointSet . IsSet ( breakpoint - > mIdx ) )
{
idx + + ;
continue ;
}
CeBreakpointBind * breakpointBind = NULL ;
if ( tryBindCount > 0 )
{
if ( breakpoint - > mRequestedLineNum > bestRequestedBindLine )
break ;
}
else
{
int lineDiff = emitEntry . mLine - breakpoint - > mLineNum ;
if ( ( lineDiff < 0 ) | | ( lineDiff > 4 ) )
break ;
if ( ( breakpoint - > mHasBound ) & & ( lineDiff ! = 0 ) )
break ;
bestRequestedBindLine = breakpoint - > mRequestedLineNum ;
}
tryBindCount + + ;
int codePos = emitEntry . mCodePos ;
if ( breakpoint - > mInstrOffset > 0 )
{
int instrOffsetLeft = breakpoint - > mInstrOffset ;
while ( instrOffsetLeft > 0 )
{
auto & opRef = * ( CeOp * ) ( & ceFunction - > mCode [ codePos ] ) ;
int instSize = mCeMachine - > GetInstSize ( ceFunction , codePos ) ;
codePos + = instSize ;
instrOffsetLeft - - ;
}
}
if ( ceFunction - > mBreakpoints . TryAdd ( codePos , NULL , & breakpointBind ) )
{
usedBreakpointSet . Set ( breakpoint - > mIdx ) ;
breakpoint - > mLineNum = emitEntry . mLine ;
breakpoint - > mHasBound = true ;
auto & opRef = * ( CeOp * ) ( & ceFunction - > mCode [ codePos ] ) ;
breakpointBind - > mPrevOpCode = opRef ;
breakpointBind - > mBreakpoint = breakpoint ;
opRef = CeOp_DbgBreak ;
}
idx + + ;
}
}
}
ceFunction - > mBreakpointVersion = mBreakpointVersion ;
}
CeDbgTypeInfo * CeDebugger : : GetDbgTypeInfo ( int typeId )
{
CeDbgTypeInfo * dbgTypeInfo = NULL ;
if ( mDbgTypeInfoMap . TryAdd ( typeId , NULL , & dbgTypeInfo ) )
{
auto type = mCeMachine - > mCeModule - > mContext - > FindTypeById ( typeId ) ;
if ( type = = NULL )
{
mDbgTypeInfoMap . Remove ( typeId ) ;
return NULL ;
}
dbgTypeInfo - > mType = type ;
auto typeInst = type - > ToTypeInstance ( ) ;
if ( typeInst ! = NULL )
{
for ( int fieldIdx = 0 ; fieldIdx < typeInst - > mFieldInstances . mSize ; fieldIdx + + )
{
auto & fieldInst = typeInst - > mFieldInstances [ fieldIdx ] ;
2022-03-15 16:33:30 -07:00
if ( fieldInst . mDataIdx > = 0 )
2022-03-08 06:27:06 -08:00
{
while ( fieldInst . mDataIdx > = dbgTypeInfo - > mFieldOffsets . mSize )
dbgTypeInfo - > mFieldOffsets . Add ( CeDbgFieldEntry ( ) ) ;
dbgTypeInfo - > mFieldOffsets [ fieldInst . mDataIdx ] . mType = fieldInst . mResolvedType ;
dbgTypeInfo - > mFieldOffsets [ fieldInst . mDataIdx ] . mDataOffset = fieldInst . mDataOffset ;
}
if ( fieldInst . mConstIdx ! = - 1 )
{
auto constant = typeInst - > mConstHolder - > GetConstantById ( fieldInst . mConstIdx ) ;
if ( ( constant ! = NULL ) & & ( BfIRConstHolder : : IsInt ( constant - > mTypeCode ) ) )
{
CeDbgTypeInfo : : ConstIntEntry constIntEntry ;
constIntEntry . mFieldIdx = fieldIdx ;
constIntEntry . mVal = constant - > mInt64 ;
dbgTypeInfo - > mConstIntEntries . Add ( constIntEntry ) ;
}
}
}
}
}
return dbgTypeInfo ;
}
CeDbgTypeInfo * CeDebugger : : GetDbgTypeInfo ( BfIRType irType )
{
if ( ( irType . mKind = = BfIRTypeData : : TypeKind_TypeId ) | | ( irType . mKind = = BfIRTypeData : : TypeKind_TypeInstId ) )
return GetDbgTypeInfo ( irType . mId ) ;
if ( irType . mKind = = BfIRTypeData : : TypeKind_TypeInstPtrId )
{
auto type = mCeMachine - > mCeModule - > mContext - > FindTypeById ( irType . mId ) ;
if ( type - > IsObjectOrInterface ( ) )
return GetDbgTypeInfo ( irType . mId ) ;
else
return GetDbgTypeInfo ( mCeMachine - > mCeModule - > CreatePointerType ( type ) - > mTypeId ) ;
}
return NULL ;
}
static bool IsNormalChar ( uint32 c )
{
return ( c < 0x80 ) ;
}
template < typename T >
static String IntTypeToString ( T val , const StringImpl & name , DwDisplayInfo * displayInfo , CeFormatInfo & formatInfo )
{
auto intDisplayType = displayInfo - > mIntDisplayType ;
if ( formatInfo . mDisplayType = = DwDisplayType_Decimal )
intDisplayType = DwIntDisplayType_Decimal ;
else if ( formatInfo . mDisplayType = = DwDisplayType_HexUpper )
intDisplayType = DwIntDisplayType_HexadecimalUpper ;
else if ( formatInfo . mDisplayType = = DwDisplayType_HexLower )
intDisplayType = DwIntDisplayType_HexadecimalLower ;
if ( intDisplayType = = DwIntDisplayType_Binary )
{
String binary ;
for ( int i = 0 ; i < sizeof ( T ) * 8 ; i + + )
{
if ( ( i ! = 0 ) & & ( i % 4 = = 0 ) )
binary = " ' " + binary ;
if ( ( i ! = 0 ) & & ( i % 16 = = 0 ) )
binary = " ' " + binary ;
binary = ( ( val & ( ( T ) 1 < < i ) ) ? " 1 " : " 0 " ) + binary ;
}
return StrFormat ( " 0b'%s \n %s " , binary . c_str ( ) , name . c_str ( ) ) ;
}
if ( intDisplayType = = DwIntDisplayType_Octal )
{
String format ;
if ( sizeof ( T ) = = 8 )
{
format = StrFormat ( " 0o%%lo \n %s " , name . c_str ( ) ) ;
}
else
format = StrFormat ( " 0o%%0%do \n %s " , sizeof ( val ) * 2 , name . c_str ( ) ) ;
2022-03-17 10:18:22 -07:00
return StrFormat ( format . c_str ( ) , ( typename std : : make_unsigned < T > : : type ) ( val ) ) ;
2022-03-08 06:27:06 -08:00
}
if ( intDisplayType = = DwIntDisplayType_HexadecimalUpper )
{
String format ;
if ( sizeof ( T ) = = 8 )
{
format = StrFormat ( " 0x%%l@ \n %s " , name . c_str ( ) ) ;
}
else
format = StrFormat ( " 0x%%0%dX \n %s " , sizeof ( val ) * 2 , name . c_str ( ) ) ;
2022-03-17 10:18:22 -07:00
return StrFormat ( format . c_str ( ) , ( typename std : : make_unsigned < T > : : type ) ( val ) ) ;
2022-03-08 06:27:06 -08:00
}
//TODO: Implement HexadecimalLower
if ( intDisplayType = = DwIntDisplayType_HexadecimalLower )
{
String format ;
if ( sizeof ( T ) = = 8 )
{
format = StrFormat ( " 0x%%l@ \n %s " , name . c_str ( ) ) ;
}
else
format = StrFormat ( " 0x%%0%dX \n %s " , sizeof ( val ) * 2 , name . c_str ( ) ) ;
2022-03-17 10:18:22 -07:00
return StrFormat ( format . c_str ( ) , ( typename std : : make_unsigned < T > : : type ) ( val ) ) ;
2022-03-08 06:27:06 -08:00
}
if ( std : : is_unsigned < T > : : value )
{
if ( sizeof ( T ) = = 8 )
{
if ( val > 0x7FFFFFFFF )
return StrFormat ( " %llu \n %s \n :editVal \t %lluUL " , val , name . c_str ( ) , val ) ;
else
return StrFormat ( " %llu \n %s " , val , name . c_str ( ) ) ;
}
else
return StrFormat ( " %u \n %s " , val , name . c_str ( ) ) ;
}
else
{
if ( sizeof ( T ) = = 8 )
{
if ( ( val > 0x7FFFFFFFF ) | | ( val < - 0x80000000LL ) )
return StrFormat ( " %lld \n %s \n :editVal \t %lldL " , val , name . c_str ( ) , val ) ;
else
return StrFormat ( " %lld \n %s " , val , name . c_str ( ) , val ) ;
}
else
return StrFormat ( " %d \n %s " , val , name . c_str ( ) ) ;
}
}
DwDisplayInfo * CeDebugger : : GetDisplayInfo ( const StringImpl & referenceId )
{
DwDisplayInfo * displayInfo = & mDebugManager - > mDefaultDisplayInfo ;
if ( ! referenceId . empty ( ) )
{
mDebugManager - > mDisplayInfos . TryGetValue ( referenceId , & displayInfo ) ;
}
return displayInfo ;
}
String CeDebugger : : GetMemberList ( BfType * type , addr_ce addr , addr_ce addrInst , bool isStatic )
{
auto typeInst = type - > ToTypeInstance ( ) ;
if ( typeInst = = NULL )
return " " ;
auto module = typeInst - > mModule ;
String retVal ;
int fieldCount = 0 ;
2022-03-15 16:33:30 -07:00
if ( ( ! isStatic ) & & ( typeInst - > mBaseType ! = NULL ) & & ( ! typeInst - > mBaseType - > IsInstanceOf ( mCompiler - > mValueTypeTypeDef ) ) )
2022-03-08 06:27:06 -08:00
{
retVal + = StrFormat ( " [base] \t this,this=%d@0x%X, nd, na, nv " , typeInst - > mBaseType - > mTypeId , addr ) ;
fieldCount + + ;
}
2022-03-15 16:33:30 -07:00
auto ceContext = mCompiler - > mCeMachine - > mCurContext ;
2022-03-08 06:27:06 -08:00
bool didStaticCtor = ceContext - > mStaticCtorExecSet . Contains ( type - > mTypeId ) ;
bool hasStaticFields = false ;
for ( auto & fieldInst : typeInst - > mFieldInstances )
{
auto fieldDef = fieldInst . GetFieldDef ( ) ;
if ( fieldDef = = NULL )
continue ;
2022-03-15 16:33:30 -07:00
2022-03-08 06:27:06 -08:00
if ( fieldDef - > mIsStatic ! = isStatic )
{
if ( fieldDef - > mIsStatic )
hasStaticFields = true ;
continue ;
}
if ( fieldCount > 0 )
retVal + = " \n " ;
retVal + = fieldDef - > mName ;
if ( fieldDef - > mIsStatic )
{
if ( didStaticCtor )
retVal + = StrFormat ( " \t comptype(%d).%s " , type - > mTypeId , fieldDef - > mName . c_str ( ) ) ;
else
retVal + = StrFormat ( " \t comptype(%d).%s " , type - > mTypeId , fieldDef - > mName . c_str ( ) ) ;
}
else
{
retVal + = " \t " ;
retVal + = fieldDef - > mName ;
retVal + = StrFormat ( " ,this=%d@0x%X " , typeInst - > mTypeId , addrInst ) ;
}
fieldCount + + ;
}
if ( hasStaticFields )
{
if ( fieldCount > 0 )
retVal + = " \n " ;
retVal + = StrFormat ( " Static values \t comptype(%d) " , typeInst - > mTypeId ) ;
}
return retVal ;
}
bool CeDebugger : : ParseFormatInfo ( const StringImpl & formatInfoStr , CeFormatInfo * formatInfo , BfPassInstance * bfPassInstance , int * assignExprOffset , String * assignExprString , String * errorString , BfTypedValue contextTypedValue )
{
String formatFlags = formatInfoStr ;
if ( assignExprOffset ! = NULL )
* assignExprOffset = - 1 ;
while ( formatFlags . length ( ) > 0 )
{
formatFlags = Trim ( formatFlags ) ;
if ( formatFlags . IsEmpty ( ) )
break ;
if ( formatFlags [ 0 ] ! = ' , ' )
{
return false ;
}
else
{
int nextComma = ( int ) formatFlags . IndexOf ( ' , ' , 1 ) ;
int quotePos = ( int ) formatFlags . IndexOf ( ' " ' , 1 ) ;
if ( ( quotePos ! = - 1 ) & & ( quotePos < nextComma ) )
{
int nextQuotePos = ( int ) formatFlags . IndexOf ( ' " ' , quotePos + 1 ) ;
if ( nextQuotePos ! = - 1 )
nextComma = ( int ) formatFlags . IndexOf ( ' , ' , nextQuotePos + 1 ) ;
}
if ( nextComma = = - 1 )
nextComma = ( int ) formatFlags . length ( ) ;
String formatCmd = formatFlags . Substring ( 1 , nextComma - 1 ) ;
formatCmd = Trim ( formatCmd ) ;
bool hadError = false ;
if ( strncmp ( formatCmd . c_str ( ) , " this= " , 5 ) = = 0 )
{
formatCmd = formatFlags . Substring ( 1 ) ;
formatCmd = Trim ( formatCmd ) ;
String thisExpr = formatCmd . Substring ( 5 ) ;
if ( thisExpr . empty ( ) )
break ;
CeEvaluationContext dbgEvaluationContext ( this , thisExpr , formatInfo ) ;
formatInfo - > mExplicitThis = dbgEvaluationContext . EvaluateInContext ( contextTypedValue ) ;
if ( dbgEvaluationContext . HadError ( ) )
{
if ( errorString ! = NULL )
* errorString = dbgEvaluationContext . GetErrorStr ( ) ;
return false ;
}
formatFlags = thisExpr . Substring ( dbgEvaluationContext . mExprString . GetLength ( ) ) ;
continue ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " count= " , 6 ) = = 0 )
{
formatCmd = formatFlags . Substring ( 1 ) ;
formatCmd = Trim ( formatCmd ) ;
String countExpr = formatCmd . Substring ( 6 ) ;
if ( countExpr . empty ( ) )
break ;
CeEvaluationContext dbgEvaluationContext ( this , countExpr , formatInfo ) ;
BfTypedValue countValue = dbgEvaluationContext . EvaluateInContext ( contextTypedValue ) ;
if ( ( countValue ) & & ( countValue . mType - > IsInteger ( ) ) )
formatInfo - > mOverrideCount = ( intptr ) ValueToInt ( countValue ) ;
if ( dbgEvaluationContext . HadError ( ) )
{
if ( errorString ! = NULL )
* errorString = dbgEvaluationContext . GetErrorStr ( ) ;
return false ;
}
formatFlags = countExpr . Substring ( dbgEvaluationContext . mExprString . GetLength ( ) ) ;
continue ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " maxcount= " , 9 ) = = 0 )
{
formatCmd = formatFlags . Substring ( 1 ) ;
formatCmd = Trim ( formatCmd ) ;
String countExpr = formatCmd . Substring ( 9 ) ;
if ( countExpr . empty ( ) )
break ;
CeEvaluationContext dbgEvaluationContext ( this , countExpr , formatInfo ) ;
BfTypedValue countValue = dbgEvaluationContext . EvaluateInContext ( contextTypedValue ) ;
if ( ( countValue ) & & ( countValue . mType - > IsInteger ( ) ) )
formatInfo - > mMaxCount = ( intptr ) ValueToInt ( countValue ) ;
if ( dbgEvaluationContext . HadError ( ) )
{
if ( errorString ! = NULL )
* errorString = dbgEvaluationContext . GetErrorStr ( ) ;
return false ;
}
formatFlags = countExpr . Substring ( dbgEvaluationContext . mExprString . GetLength ( ) ) ;
continue ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " arraysize= " , 10 ) = = 0 )
{
formatCmd = formatFlags . Substring ( 1 ) ;
formatCmd = Trim ( formatCmd ) ;
String countExpr = formatCmd . Substring ( 10 ) ;
if ( countExpr . empty ( ) )
break ;
CeEvaluationContext dbgEvaluationContext ( this , countExpr , formatInfo ) ;
BfTypedValue countValue = dbgEvaluationContext . EvaluateInContext ( contextTypedValue ) ;
if ( ( countValue ) & & ( countValue . mType - > IsInteger ( ) ) )
formatInfo - > mArrayLength = ( intptr ) ValueToInt ( countValue ) ;
if ( dbgEvaluationContext . HadError ( ) )
{
if ( errorString ! = NULL )
* errorString = dbgEvaluationContext . GetErrorStr ( ) ;
return false ;
}
formatFlags = countExpr . Substring ( dbgEvaluationContext . mExprString . GetLength ( ) ) ;
continue ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " assign= " , 7 ) = = 0 )
{
formatCmd = formatFlags . Substring ( 1 ) ;
formatCmd = Trim ( formatCmd ) ;
String assignExpr = formatCmd . Substring ( 7 ) ;
if ( assignExpr . empty ( ) )
break ;
CeEvaluationContext dbgEvaluationContext ( this , assignExpr , formatInfo ) ;
if ( dbgEvaluationContext . HadError ( ) )
{
if ( errorString ! = NULL )
* errorString = dbgEvaluationContext . GetErrorStr ( ) ;
return false ;
}
if ( assignExprOffset ! = NULL )
{
//TODO: Keep track of the offset directly, this is a hack
* assignExprOffset = ( int ) formatInfoStr . IndexOf ( " assign= " ) + 7 ;
}
if ( assignExprString ! = NULL )
* assignExprString = dbgEvaluationContext . mExprNode - > ToString ( ) ;
formatFlags = assignExpr . Substring ( dbgEvaluationContext . mExprNode - > GetSrcEnd ( ) ) ;
continue ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " refid= " , 6 ) = = 0 )
{
formatInfo - > mReferenceId = formatCmd . Substring ( 6 ) ;
if ( formatInfo - > mReferenceId [ 0 ] = = ' \" ' )
formatInfo - > mReferenceId = formatInfo - > mReferenceId . Substring ( 1 , formatInfo - > mReferenceId . length ( ) - 2 ) ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " _= " , 2 ) = = 0 )
{
formatInfo - > mSubjectExpr = formatCmd . Substring ( 2 ) ;
if ( formatInfo - > mSubjectExpr [ 0 ] = = ' \" ' )
formatInfo - > mSubjectExpr = formatInfo - > mSubjectExpr . Substring ( 1 , formatInfo - > mSubjectExpr . length ( ) - 2 ) ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " expectedType= " , 13 ) = = 0 )
{
formatInfo - > mExpectedType = formatCmd . Substring ( 13 ) ;
if ( formatInfo - > mExpectedType [ 0 ] = = ' \" ' )
formatInfo - > mExpectedType = formatInfo - > mExpectedType . Substring ( 1 , formatInfo - > mExpectedType . length ( ) - 2 ) ;
}
else if ( strncmp ( formatCmd . c_str ( ) , " namespaceSearch= " , 16 ) = = 0 )
{
formatInfo - > mNamespaceSearch = formatCmd . Substring ( 16 ) ;
if ( formatInfo - > mNamespaceSearch [ 0 ] = = ' \" ' )
formatInfo - > mNamespaceSearch = formatInfo - > mNamespaceSearch . Substring ( 1 , formatInfo - > mNamespaceSearch . length ( ) - 2 ) ;
}
else if ( formatCmd = = " d " )
{
formatInfo - > mDisplayType = DwDisplayType_Decimal ;
}
else if ( formatCmd = = " x " )
{
formatInfo - > mDisplayType = DwDisplayType_HexLower ;
}
else if ( formatCmd = = " X " )
{
formatInfo - > mDisplayType = DwDisplayType_HexUpper ;
}
else if ( formatCmd = = " s " )
{
formatInfo - > mHidePointers = true ;
formatInfo - > mDisplayType = DwDisplayType_Ascii ;
}
else if ( formatCmd = = " s8 " )
{
formatInfo - > mHidePointers = true ;
formatInfo - > mDisplayType = DwDisplayType_Utf8 ;
}
else if ( formatCmd = = " s16 " )
{
formatInfo - > mHidePointers = true ;
formatInfo - > mDisplayType = DwDisplayType_Utf16 ;
}
else if ( formatCmd = = " s32 " )
{
formatInfo - > mHidePointers = true ;
formatInfo - > mDisplayType = DwDisplayType_Utf32 ;
}
else if ( formatCmd = = " nd " )
{
formatInfo - > mIgnoreDerivedClassInfo = true ;
}
else if ( formatCmd = = " na " )
{
formatInfo - > mHidePointers = true ;
}
else if ( formatCmd = = " nm " )
{
formatInfo - > mNoMembers = true ;
}
else if ( formatCmd = = " ne " )
{
formatInfo - > mNoEdit = true ;
}
else if ( formatCmd = = " nv " )
{
formatInfo - > mNoVisualizers = true ;
}
else if ( formatCmd = = " rawStr " )
{
formatInfo - > mRawString = true ;
}
else if ( ( ( ! formatCmd . IsEmpty ( ) ) & & ( ( formatCmd [ 0 ] > = ' 0 ' ) & & ( formatCmd [ 0 ] < = ' 9 ' ) ) ) | |
( formatCmd . StartsWith ( " ( " ) ) )
{
String countExpr = formatCmd ;
if ( countExpr . empty ( ) )
break ;
CeEvaluationContext dbgEvaluationContext ( this , countExpr , formatInfo ) ;
BfTypedValue countValue = dbgEvaluationContext . EvaluateInContext ( contextTypedValue ) ;
if ( ( countValue ) & & ( countValue . mType - > IsInteger ( ) ) )
formatInfo - > mArrayLength = ( intptr ) ValueToInt ( countValue ) ;
if ( dbgEvaluationContext . HadError ( ) )
{
if ( errorString ! = NULL )
* errorString = dbgEvaluationContext . GetErrorStr ( ) ;
return false ;
}
formatFlags = dbgEvaluationContext . mExprString ;
continue ;
}
else
hadError = true ;
if ( hadError )
{
if ( errorString ! = NULL )
* errorString = " Invalid format flags " ;
return false ;
}
formatFlags = formatFlags . Substring ( nextComma ) ;
}
}
return true ;
}
String CeDebugger : : MaybeQuoteFormatInfoParam ( const StringImpl & str )
{
bool needsQuote = false ;
for ( int i = 0 ; i < ( int ) str . length ( ) ; i + + )
{
char c = str [ i ] ;
if ( c = = ' , ' )
needsQuote = true ;
}
if ( ! needsQuote )
return str ;
String qStr = " \" " ;
qStr + = str ;
qStr + = " \" " ;
return qStr ;
}
BfTypedValue CeDebugger : : EvaluateInContext ( const BfTypedValue & contextTypedValue , const StringImpl & subExpr , CeFormatInfo * formatInfo , String * outReferenceId , String * outErrors )
{
CeEvaluationContext dbgEvaluationContext ( this , subExpr , formatInfo , contextTypedValue ) ;
// if (formatInfo != NULL)
// {
// dbgEvaluationContext.mDbgExprEvaluator->mSubjectExpr = formatInfo->mSubjectExpr;
// }
//dbgEvaluationContext.mDbgExprEvaluator->mReferenceId = outReferenceId;
SetAndRestoreValue < CeEvaluationContext * > prevEvalContext ( mCurEvaluationContext , & dbgEvaluationContext ) ;
//mCountResultOverride = -1;
auto result = dbgEvaluationContext . EvaluateInContext ( contextTypedValue ) ;
// if ((formatInfo != NULL) && (dbgEvaluationContext.mDbgExprEvaluator->mCountResultOverride != -1))
// formatInfo->mOverrideCount = dbgEvaluationContext.mDbgExprEvaluator->mCountResultOverride;
if ( dbgEvaluationContext . mPassInstance - > HasFailed ( ) )
{
if ( outErrors ! = NULL )
{
int errIdx = 0 ;
for ( auto err : dbgEvaluationContext . mPassInstance - > mErrors )
{
if ( errIdx > 0 )
( * outErrors ) + = " \n " ;
( * outErrors ) + = err - > mError ;
errIdx + + ;
}
}
return BfTypedValue ( ) ;
}
return result ;
}
void CeDebugger : : DbgVisFailed ( DebugVisualizerEntry * debugVis , const StringImpl & evalString , const StringImpl & errors )
{
bool onlyMemError = errors . StartsWith ( " Failed to read " ) & & ! errors . Contains ( ' \n ' ) ;
if ( ( ! debugVis - > mShowedError ) & & ( ! onlyMemError ) )
{
debugVis - > mShowedError = true ;
String errStr = StrFormat ( " DbgVis '%s' failed while evaluating condition '%s' \n " , debugVis - > mName . c_str ( ) , evalString . c_str ( ) ) ;
String spacedErrors = errors ;
spacedErrors . Insert ( 0 , " " ) ;
spacedErrors . Replace ( " \n " , " \n " ) ;
errStr + = spacedErrors ;
OutputMessage ( errStr ) ;
}
}
bool CeDebugger : : EvalCondition ( DebugVisualizerEntry * debugVis , BfTypedValue typedVal , CeFormatInfo & formatInfo , const StringImpl & condition , const Array < String > & dbgVisWildcardCaptures , String & errorStr )
{
auto ceModule = mCeMachine - > mCeModule ;
CeFormatInfo displayStrFormatInfo = formatInfo ;
displayStrFormatInfo . mHidePointers = false ;
displayStrFormatInfo . mRawString = false ;
String errors ;
const String conditionStr = mDebugManager - > mDebugVisualizers - > DoStringReplace ( condition , dbgVisWildcardCaptures ) ;
BfTypedValue evalResult = EvaluateInContext ( typedVal , conditionStr , & displayStrFormatInfo , NULL , & errors ) ;
if ( ( ! evalResult ) | | ( ! evalResult . mType - > IsBoolean ( ) ) )
{
if ( formatInfo . mRawString )
return false ;
errorStr + = " <DbgVis Failed> " ;
DbgVisFailed ( debugVis , conditionStr , errors ) ;
return false ;
}
evalResult = ceModule - > LoadValue ( evalResult ) ;
if ( auto constant = ceModule - > mBfIRBuilder - > GetConstant ( evalResult . mValue ) )
{
if ( constant - > mTypeCode = = BfTypeCode_Boolean )
return constant - > mBool ;
}
return false ;
}
String CeDebugger : : GetArrayItems ( DebugVisualizerEntry * debugVis , BfType * valueType , BfTypedValue & curNode , int & count , String * outContinuationData )
{
CeEvaluationContext conditionEvaluationContext ( this , debugVis - > mCondition ) ;
auto ceModule = mCeMachine - > mCeModule ;
String addrs ;
bool checkLeft = true ;
addr_ce curNodeAddr = 0 ;
int usedCount = 0 ;
while ( usedCount < count )
{
if ( ( ! curNode ) | | ( ! curNode . mType - > IsPointer ( ) ) )
break ;
curNode = ceModule - > LoadValue ( curNode ) ;
BfTypedValue condVal = conditionEvaluationContext . EvaluateInContext ( curNode ) ;
if ( ! condVal )
break ;
auto ceTypedVal = GetAddr ( curNode ) ;
if ( ! ceTypedVal )
break ;
if ( ValueToInt ( condVal ) ! = 0 )
{
auto val = curNode ;
if ( valueType = = NULL )
{
//String typeAddr = val.mType->ToStringRaw();
String typeAddr = StrFormat ( " comptype(%d) " , val . mType - > mTypeId ) ;
// RPad
typeAddr . Append ( ' ' , sizeof ( addr_ce ) * 2 - ( int ) typeAddr . length ( ) ) ;
addrs + = typeAddr ;
}
2022-03-15 16:33:30 -07:00
String addr = EncodeDataPtr ( ( addr_ce ) ceTypedVal . mAddr , false ) ;
2022-03-08 06:27:06 -08:00
addrs + = addr ;
usedCount + + ;
}
auto elemType = curNode . mType - > GetUnderlyingType ( ) ;
2022-03-15 16:33:30 -07:00
curNodeAddr = ( addr_ce ) ceTypedVal . mAddr + elemType - > GetStride ( ) ;
2022-03-08 06:27:06 -08:00
curNode . mValue = ceModule - > mBfIRBuilder - > CreateIntToPtr ( curNodeAddr , ceModule - > mBfIRBuilder - > MapType ( curNode . mType ) ) ;
}
count = usedCount ;
if ( outContinuationData ! = NULL )
{
* outContinuationData + = EncodeDataPtr ( debugVis , false ) + EncodeDataPtr ( valueType , false ) +
EncodeDataPtr ( curNode . mType , false ) + EncodeDataPtr ( curNodeAddr , false ) ;
}
return addrs ;
}
String CeDebugger : : GetLinkedListItems ( DebugVisualizerEntry * debugVis , addr_ce endNodePtr , BfType * valueType , BfTypedValue & curNode , int & count , String * outContinuationData )
{
CeEvaluationContext nextEvaluationContext ( this , debugVis - > mNextPointer ) ;
CeEvaluationContext valueEvaluationContext ( this , debugVis - > mValuePointer ) ;
2022-03-15 16:33:30 -07:00
auto ceModule = mCeMachine - > mCeModule ;
2022-03-08 06:27:06 -08:00
String addrs ;
bool checkLeft = true ;
2022-03-15 16:33:30 -07:00
int mapIdx ;
for ( mapIdx = 0 ; mapIdx < count ; mapIdx + + )
{
CeTypedValue ceNodeVal = GetAddr ( curNode ) ;
if ( ! ceNodeVal )
break ;
2022-03-08 06:27:06 -08:00
2022-03-15 16:33:30 -07:00
if ( ceNodeVal . mAddr = = endNodePtr )
break ;
BfTypedValue val = valueEvaluationContext . EvaluateInContext ( curNode ) ;
if ( ! val )
break ;
auto ceVal = GetAddr ( val ) ;
if ( ! ceVal )
break ;
if ( ceVal . mAddr = = 0 )
break ;
if ( valueType = = NULL )
{
String typeAddr = StrFormat ( " comptype(%d) " , val . mType - > mTypeId ) ;
// RPad
typeAddr . Append ( ' ' , sizeof ( addr_ce ) * 2 - ( int ) typeAddr . length ( ) ) ;
addrs + = typeAddr ;
}
String addr = EncodeDataPtr ( ( addr_ce ) ceVal . mAddr , false ) ;
addrs + = addr ;
curNode = nextEvaluationContext . EvaluateInContext ( curNode ) ;
}
count = mapIdx ;
if ( outContinuationData ! = NULL )
{
CeTypedValue ceNodeVal = GetAddr ( curNode ) ;
* outContinuationData + = EncodeDataPtr ( debugVis , false ) + EncodeDataPtr ( endNodePtr , false ) + EncodeDataPtr ( valueType , false ) +
EncodeDataPtr ( curNode . mType , false ) + EncodeDataPtr ( ( addr_ce ) ceNodeVal . mAddr , false ) ;
}
2022-03-08 06:27:06 -08:00
return addrs ;
}
String CeDebugger : : GetDictionaryItems ( DebugVisualizerEntry * debugVis , BfTypedValue dictValue , int bucketIdx , int nodeIdx , int & count , String * outContinuationData )
{
CeEvaluationContext nextEvaluationContext ( this , debugVis - > mNextPointer ) ;
2022-03-15 16:33:30 -07:00
auto ceModule = mCeMachine - > mCeModule ;
2022-03-08 06:27:06 -08:00
BfTypedValue bucketsPtr = EvaluateInContext ( dictValue , debugVis - > mBuckets ) ;
BfTypedValue entriesPtr = EvaluateInContext ( dictValue , debugVis - > mEntries ) ;
if ( ( ! bucketsPtr ) | | ( ! entriesPtr ) )
{
count = - 1 ;
return " " ;
}
2022-03-15 16:33:30 -07:00
auto ceDictTypedVal = GetAddr ( dictValue ) ;
if ( ! ceDictTypedVal )
return " " ;
auto ceBucketsTypedVal = GetAddr ( bucketsPtr ) ;
if ( ! ceBucketsTypedVal )
return " " ;
2022-03-08 06:27:06 -08:00
String addrs ;
2022-03-15 16:33:30 -07:00
if ( ( ! entriesPtr ) | | ( ! entriesPtr . mType - > IsPointer ( ) ) )
return " " ;
if ( ( ! bucketsPtr ) | | ( ! bucketsPtr . mType - > IsPointer ( ) ) )
return " " ;
auto entryType = entriesPtr . mType - > GetUnderlyingType ( ) ;
int entrySize = entryType - > GetStride ( ) ;
int bucketIdxSize = bucketsPtr . mType - > GetUnderlyingType ( ) - > GetStride ( ) ;
auto ceElemTypedVal = GetAddr ( entriesPtr ) ;
if ( ! ceElemTypedVal )
return " " ;
bool checkLeft = true ;
int encodeCount = 0 ;
while ( encodeCount < count )
{
if ( nodeIdx ! = - 1 )
{
addr_ce entryAddr = ( addr_ce ) ceElemTypedVal . mAddr + ( nodeIdx * entrySize ) ;
BfTypedValue entryValue = BfTypedValue ( ceModule - > mBfIRBuilder - > CreateConstAggCE ( ceModule - > mBfIRBuilder - > MapType ( entryType ) , entryAddr ) , entryType ) ;
addrs + = EncodeDataPtr ( entryAddr , false ) ;
BfTypedValue nextValue = nextEvaluationContext . EvaluateInContext ( entryValue ) ;
if ( ( ! nextValue ) | | ( ! nextValue . mType - > IsInteger ( ) ) )
{
break ;
}
nodeIdx = ( int ) ValueToInt ( nextValue ) ;
encodeCount + + ;
}
else
{
if ( bucketIdxSize = = 4 )
nodeIdx = ReadMemory < int > ( ceBucketsTypedVal . mAddr + bucketIdx * sizeof ( int32 ) ) ;
else
nodeIdx = ( int ) ReadMemory < int64 > ( ceBucketsTypedVal . mAddr + bucketIdx * sizeof ( int64 ) ) ;
bucketIdx + + ;
}
}
count = encodeCount ;
if ( outContinuationData ! = NULL )
{
* outContinuationData + = EncodeDataPtr ( debugVis , false ) + EncodeDataPtr ( dictValue . mType , false ) + EncodeDataPtr ( ( addr_ce ) ceDictTypedVal . mAddr , false ) +
EncodeDataPtr ( ( addr_ce ) bucketIdx , false ) + EncodeDataPtr ( ( addr_ce ) nodeIdx , false ) ;
}
2022-03-08 06:27:06 -08:00
return addrs ;
}
String CeDebugger : : GetTreeItems ( DebugVisualizerEntry * debugVis , Array < addr_ce > & parentList , BfType * & valueType , BfTypedValue & curNode , int count , String * outContinuationData )
{
CeEvaluationContext leftEvaluationContext ( this , debugVis - > mLeftPointer ) ;
CeEvaluationContext rightEvaluationContext ( this , debugVis - > mRightPointer ) ;
CeEvaluationContext valueEvaluationContext ( this , debugVis - > mValuePointer ) ;
CeEvaluationContext conditionEvaluationContext ( this , debugVis - > mCondition ) ;
String addrs ;
//TODO:
// bool checkLeft = true;
//
// if ((curNode.mPtr & 2) != 0) // Flag from continuation
// {
// checkLeft = false;
// curNode.mPtr &= (addr_ce)~2;
// }
//
// HashSet<intptr> seenAddrs;
//
// for (int mapIdx = 0; mapIdx < count; mapIdx++)
// {
// BfTypedValue readNode;
// while (true)
// {
// bool checkNode = (curNode.mPtr & 1) == 0;
//
// readNode = curNode;
// readNode.mPtr &= (addr_ce)~1;
//
// if (checkLeft)
// {
// BfTypedValue leftValue = leftEvaluationContext.EvaluateInContext(readNode);
// bool isEmpty = leftValue.mPtr == NULL;
// if ((leftValue) && (conditionEvaluationContext.HasExpression()))
// {
// auto condValue = conditionEvaluationContext.EvaluateInContext(leftValue);
// if (condValue)
// isEmpty = !condValue.mBool;
// }
// if (isEmpty)
// {
// checkLeft = false;
// break; // Handle node
// }
//
// parentList.push_back(curNode.mPtr);
// curNode = leftValue;
// }
// else if (checkNode)
// {
// break; // Handle node
// }
// else
// {
// BfTypedValue rightValue = rightEvaluationContext.EvaluateInContext(readNode);
// bool isEmpty = rightValue.mPtr == NULL;
// if ((rightValue) && (conditionEvaluationContext.HasExpression()))
// {
// auto condValue = conditionEvaluationContext.EvaluateInContext(rightValue);
// if (condValue)
// isEmpty = !condValue.mBool;
// }
// if (!isEmpty)
// {
// curNode = rightValue;
// checkLeft = true;
// }
// else
// {
// if (parentList.size() == 0)
// {
// // Failed
// break;
// }
//
// curNode.mPtr = parentList.back();
// parentList.pop_back();
// continue; // Don't check against seenAddrs
// }
// }
//
// if (!seenAddrs.Add(curNode.mPtr))
// {
// // Failed!
// return "";
// }
// }
//
//
// BfTypedValue val = valueEvaluationContext.EvaluateInContext(readNode);
// if (valueType == NULL)
// valueType = val.mType;
//
// String addr = EncodeDataPtr(val.mPtr, false);
// addrs += addr;
//
// curNode.mPtr |= 1; // Node handled
// }
//
// if (!checkLeft)
// curNode.mPtr |= 2;
//
// if (outContinuationData != NULL)
// {
// *outContinuationData += EncodeDataPtr(debugVis, false) + EncodeDataPtr(valueType, false) + EncodeDataPtr(curNode.mType, false) + EncodeDataPtr(curNode.mPtr, false);
// for (auto parent : parentList)
// *outContinuationData += EncodeDataPtr(parent, false);
// }
return addrs ;
}
String CeDebugger : : GetCollectionContinuation ( const StringImpl & continuationData , int callStackIdx , int count )
{
if ( ! mCeMachine - > mDbgPaused )
return " " ;
auto ceModule = mCeMachine - > mCeModule ;
const char * dataPtr = continuationData . c_str ( ) ;
DebugVisualizerEntry * debugVis = ( DebugVisualizerEntry * ) DecodeLocalDataPtr ( dataPtr ) ;
if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_TreeItems )
{
//TODO:
// DbgType* valueType = (DbgType*)DecodeLocalDataPtr(dataPtr);
// BfTypedValue curNode;
// curNode.mType = (DbgType*)DecodeLocalDataPtr(dataPtr);
// curNode.mPtr = DecodeTargetDataPtr(dataPtr);
//
// Array<addr_ce> parentList;
// String newContinuationData;
// while (*dataPtr != 0)
// parentList.push_back(DecodeTargetDataPtr(dataPtr));
//
// String retVal = GetTreeItems(dbgCompileUnit, debugVis, parentList, valueType, curNode, count, &newContinuationData);
// retVal += "\n" + newContinuationData;
// return retVal;
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_LinkedList )
2022-03-15 16:33:30 -07:00
{
addr_ce endNodePtr = DecodeTargetDataPtr ( dataPtr ) ;
BfType * valueType = ( BfType * ) DecodeLocalDataPtr ( dataPtr ) ;
BfType * nodeType = ( BfType * ) DecodeLocalDataPtr ( dataPtr ) ;
BfTypedValue curNode = BfTypedValue (
ceModule - > mBfIRBuilder - > CreateIntToPtr ( DecodeTargetDataPtr ( dataPtr ) , ceModule - > mBfIRBuilder - > MapType ( nodeType ) ) ,
nodeType ) ;
String newContinuationData ;
if ( count < 0 )
count = 3 ;
String retVal = GetLinkedListItems ( debugVis , endNodePtr , valueType , curNode , count , & newContinuationData ) ;
retVal + = " \n " + newContinuationData ;
return retVal ;
2022-03-08 06:27:06 -08:00
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_Array )
{
BfType * valueType = ( BfType * ) DecodeLocalDataPtr ( dataPtr ) ;
auto nodeType = ( BfType * ) DecodeLocalDataPtr ( dataPtr ) ;
BfTypedValue curNode = BfTypedValue (
ceModule - > mBfIRBuilder - > CreateIntToPtr ( DecodeTargetDataPtr ( dataPtr ) , ceModule - > mBfIRBuilder - > MapType ( nodeType ) ) ,
nodeType ) ;
String newContinuationData ;
if ( count < 0 )
count = 3 ;
String retVal = GetArrayItems ( debugVis , valueType , curNode , count , & newContinuationData ) ;
retVal + = " \n " + newContinuationData ;
return retVal ;
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_Dictionary )
2022-03-15 16:33:30 -07:00
{
auto dictValueType = ( BfType * ) DecodeLocalDataPtr ( dataPtr ) ;
BfTypedValue dictValue = BfTypedValue (
ceModule - > mBfIRBuilder - > CreateIntToPtr ( DecodeTargetDataPtr ( dataPtr ) , ceModule - > mBfIRBuilder - > MapType ( dictValueType ) ) ,
dictValueType ) ;
int bucketIdx = ( int ) DecodeTargetDataPtr ( dataPtr ) ;
int nodeIdx = ( int ) DecodeTargetDataPtr ( dataPtr ) ;
String newContinuationData ;
String retVal = GetDictionaryItems ( debugVis , dictValue , bucketIdx , nodeIdx , count , & newContinuationData ) ;
retVal + = " \n " + newContinuationData ;
return retVal ;
2022-03-08 06:27:06 -08:00
}
return " " ;
}
2022-03-15 16:33:30 -07:00
CeTypedValue CeDebugger : : GetAddr ( BfConstant * constant , BfType * type )
2022-03-08 06:27:06 -08:00
{
auto module = mCeMachine - > mCeModule ;
auto ceContext = mCeMachine - > mCurContext ;
if ( constant - > mConstType = = BfConstType_GlobalVar )
{
auto globalVar = ( BfGlobalVar * ) constant ;
String varName ( globalVar - > mName ) ;
if ( varName . StartsWith ( " __bfStrObj " ) )
{
int stringId = atoi ( varName . c_str ( ) + 10 ) ;
auto addr = ceContext - > GetString ( stringId ) ;
return CeTypedValue ( addr , globalVar - > mType ) ;
}
else if ( varName . StartsWith ( " __bfStrData " ) )
{
auto stringType = module - > ResolveTypeDef ( module - > mCompiler - > mStringTypeDef ) - > ToTypeInstance ( ) ;
int stringId = atoi ( varName . c_str ( ) + 11 ) ;
auto addr = ceContext - > GetString ( stringId ) + stringType - > mInstSize ;
return CeTypedValue ( addr , globalVar - > mType ) ;
}
CeStaticFieldInfo * fieldInfo = NULL ;
if ( ceContext - > mStaticFieldMap . TryAdd ( globalVar - > mName , NULL , & fieldInfo ) )
{
auto dbgTypeInfo = GetDbgTypeInfo ( globalVar - > mType ) ;
if ( dbgTypeInfo ! = NULL )
{
uint8 * ptr = ceContext - > CeMalloc ( dbgTypeInfo - > mType - > mSize ) ;
if ( dbgTypeInfo - > mType - > mSize > 0 )
memset ( ptr , 0 , dbgTypeInfo - > mType - > mSize ) ;
fieldInfo - > mAddr = ( addr_ce ) ( ptr - ceContext - > mMemory . mVals ) ;
}
else
fieldInfo - > mAddr = 0 ;
}
return CeTypedValue ( fieldInfo - > mAddr , globalVar - > mType ) ;
}
2022-03-15 16:33:30 -07:00
else if ( constant - > mTypeCode = = BfTypeCode_StringId )
{
auto stringType = module - > ResolveTypeDef ( module - > mCompiler - > mStringTypeDef ) - > ToTypeInstance ( ) ;
if ( ( type ! = NULL ) & & ( type - > IsPointer ( ) ) )
{
BfType * charType = module - > GetPrimitiveType ( BfTypeCode_Char8 ) ;
BfType * charPtrType = module - > CreatePointerType ( charType ) ;
auto addr = ceContext - > GetString ( constant - > mInt32 ) + stringType - > mInstSize ;
return CeTypedValue ( addr , module - > mBfIRBuilder - > MapType ( charPtrType ) ) ;
}
else
{
auto addr = ceContext - > GetString ( constant - > mInt32 ) ;
return CeTypedValue ( addr , module - > mBfIRBuilder - > MapType ( stringType ) ) ;
}
}
2022-03-08 06:27:06 -08:00
else if ( constant - > mConstType = = BfConstType_AggCE )
{
auto aggCE = ( BfConstantAggCE * ) constant ;
return CeTypedValue ( aggCE - > mCEAddr , aggCE - > mType ) ;
}
else if ( constant - > mConstType = = BfConstType_BitCast )
{
auto constBitCast = ( BfConstantBitCast * ) constant ;
auto val = GetAddr ( module - > mBfIRBuilder - > GetConstantById ( constBitCast - > mTarget ) ) ;
if ( ! val )
return val ;
return CeTypedValue ( val . mAddr , constBitCast - > mToType ) ;
}
else if ( constant - > mConstType = = BfConstType_IntToPtr )
{
auto fromPtrToInt = ( BfConstantIntToPtr * ) constant ;
auto val = GetAddr ( module - > mBfIRBuilder - > GetConstantById ( fromPtrToInt - > mTarget ) ) ;
if ( ! val )
return val ;
return CeTypedValue ( val . mAddr , fromPtrToInt - > mToType ) ;
}
else if ( constant - > mConstType = = BfConstType_GEP32_1 )
{
auto gepConst = ( BfConstantGEP32_1 * ) constant ;
auto constant = module - > mBfIRBuilder - > GetConstantById ( gepConst - > mTarget ) ;
auto typedVal = GetAddr ( constant ) ;
if ( ! typedVal )
return CeTypedValue ( ) ;
auto dbgTypeInfo = GetDbgTypeInfo ( typedVal . mType ) ;
if ( dbgTypeInfo = = NULL )
return CeTypedValue ( ) ;
auto addr = typedVal . mAddr ;
if ( gepConst - > mIdx0 ! = 0 )
addr + = gepConst - > mIdx0 * dbgTypeInfo - > mType - > GetUnderlyingType ( ) - > GetStride ( ) ;
return CeTypedValue ( addr , module - > mBfIRBuilder - > MapType ( dbgTypeInfo - > mType ) ) ;
}
else if ( constant - > mConstType = = BfConstType_GEP32_2 )
{
auto gepConst = ( BfConstantGEP32_2 * ) constant ;
auto constant = module - > mBfIRBuilder - > GetConstantById ( gepConst - > mTarget ) ;
auto typedVal = GetAddr ( constant ) ;
if ( ! typedVal . mAddr )
return CeTypedValue ( ) ;
auto dbgTypeInfo = GetDbgTypeInfo ( typedVal . mType ) ;
2022-03-17 08:47:34 -07:00
if ( ( dbgTypeInfo ! = NULL ) & &
( ( dbgTypeInfo - > mType - > IsPointer ( ) ) | | ( ( dbgTypeInfo - > mType - > IsRef ( ) ) ) ) )
2022-03-08 06:27:06 -08:00
dbgTypeInfo = GetDbgTypeInfo ( dbgTypeInfo - > mType - > GetUnderlyingType ( ) - > mTypeId ) ;
if ( dbgTypeInfo = = NULL )
return CeTypedValue ( ) ;
auto addr = typedVal . mAddr ;
if ( gepConst - > mIdx0 ! = 0 )
addr + = gepConst - > mIdx0 * dbgTypeInfo - > mType - > GetStride ( ) ;
if ( gepConst - > mIdx1 ! = 0 )
addr + = dbgTypeInfo - > mFieldOffsets [ gepConst - > mIdx1 ] . mDataOffset ;
2022-03-15 16:33:30 -07:00
BfType * ptrType = NULL ;
if ( gepConst - > mIdx1 = = 0 )
{
auto typeInst = dbgTypeInfo - > mType - > ToTypeInstance ( ) ;
if ( ( typeInst ! = NULL ) & & ( typeInst - > mBaseType ! = NULL ) )
{
ptrType = typeInst - > mBaseType ;
if ( ! ptrType - > IsValueType ( ) )
ptrType = module - > CreatePointerType ( ptrType ) ;
}
}
if ( ptrType = = NULL )
{
if ( gepConst - > mIdx1 > dbgTypeInfo - > mFieldOffsets . mSize )
return CeTypedValue ( ) ;
ptrType = module - > CreatePointerType ( dbgTypeInfo - > mFieldOffsets [ gepConst - > mIdx1 ] . mType ) ;
}
2022-03-08 06:27:06 -08:00
return CeTypedValue ( addr , module - > mBfIRBuilder - > MapType ( ptrType ) ) ;
}
else if ( ( constant - > mTypeCode = = BfTypeCode_Int32 ) | |
( constant - > mTypeCode = = BfTypeCode_Int64 ) | |
( constant - > mTypeCode = = BfTypeCode_IntPtr ) )
{
2022-03-15 16:33:30 -07:00
return CeTypedValue ( constant - > mInt64 , module - > mBfIRBuilder - > GetPrimitiveType ( constant - > mTypeCode ) ) ;
2022-03-08 06:27:06 -08:00
}
return CeTypedValue ( ) ;
}
CeTypedValue CeDebugger : : GetAddr ( const BfTypedValue typedVal )
{
auto constant = mCeMachine - > mCeModule - > mBfIRBuilder - > GetConstant ( typedVal . mValue ) ;
if ( constant = = NULL )
return CeTypedValue ( ) ;
2022-03-15 16:33:30 -07:00
return GetAddr ( constant , typedVal . mType ) ;
2022-03-08 06:27:06 -08:00
}
# define GET_FROM(ptr, T) *((T*)(ptr += sizeof(T)) - 1)
String CeDebugger : : ReadString ( BfTypeCode charType , intptr addr , intptr maxLength , CeFormatInfo & formatInfo )
{
int origMaxLength = ( int ) maxLength ;
if ( addr = = 0 )
return " " ;
BP_ZONE ( " WinDebugger::ReadString " ) ;
String retVal = " \" " ;
bool wasTerminated = false ;
String valString ;
intptr maxShowSize = 255 ;
if ( maxLength = = - 1 )
maxLength = formatInfo . mOverrideCount ;
else if ( formatInfo . mOverrideCount ! = - 1 )
maxLength = BF_MIN ( formatInfo . mOverrideCount , maxLength ) ;
if ( formatInfo . mMaxCount ! = - 1 )
maxLength = BF_MIN ( formatInfo . mMaxCount , maxLength ) ;
if ( maxLength = = - 1 )
maxLength = 8 * 1024 * 1024 ; // Is 8MB crazy?
if ( ! formatInfo . mRawString )
maxLength = BF_MIN ( maxLength , maxShowSize ) ;
//EnableMemCache();
bool readFailed = false ;
intptr strPtr = addr ;
int charLen = 1 ;
if ( charType = = BfTypeCode_Char16 )
charLen = 2 ;
else if ( charType = = BfTypeCode_Char32 )
charLen = 4 ;
bool isUTF8 = formatInfo . mDisplayType = = DwDisplayType_Utf8 ;
int readSize = BF_MIN ( 1024 , ( int ) maxLength * charLen ) ;
uint8 buf [ 1024 ] ;
uint8 * bufPtr = NULL ;
uint8 * bufEnd = NULL ;
bool hasHighAscii = false ;
int i ;
for ( i = 0 ; i < maxLength ; i + + )
{
if ( bufPtr > = bufEnd )
{
while ( true )
{
if ( readSize < charLen )
{
readFailed = true ;
break ;
}
if ( ReadMemory ( strPtr , readSize , buf ) )
break ;
readSize / = 2 ;
}
if ( readFailed )
break ;
bufPtr = buf ;
bufEnd = buf + readSize ;
}
switch ( charLen )
{
case 1 :
{
char c = GET_FROM ( bufPtr , char ) ;
if ( ( c ! = 0 ) | | ( formatInfo . mOverrideCount ! = - 1 ) )
{
if ( ( uint8 ) c > = 0x80 )
hasHighAscii = true ;
valString . Append ( c ) ;
}
else
wasTerminated = true ;
}
break ;
case 2 :
{
uint16 c16 = GET_FROM ( bufPtr , uint16 ) ;
if ( ( c16 ! = 0 ) | | ( formatInfo . mOverrideCount ! = - 1 ) )
{
char str [ 8 ] ;
u8_toutf8 ( str , 8 , c16 ) ;
valString + = str ;
}
else
wasTerminated = true ;
}
break ;
case 4 :
{
uint32 c32 = GET_FROM ( bufPtr , uint32 ) ;
if ( ( c32 ! = 0 ) | | ( formatInfo . mOverrideCount ! = - 1 ) )
{
char str [ 8 ] ;
u8_toutf8 ( str , 8 , c32 ) ;
valString + = str ;
}
else
wasTerminated = true ;
}
break ;
}
if ( ( wasTerminated ) & & ( formatInfo . mOverrideCount ! = - 1 ) )
{
valString + = ' \x00 ' ;
wasTerminated = false ;
}
if ( ( wasTerminated ) | | ( readFailed ) )
{
break ;
}
strPtr + = charLen ;
}
//DisableMemCache();
if ( formatInfo . mOverrideCount ! = - 1 )
{
if ( i = = formatInfo . mOverrideCount )
wasTerminated = true ;
}
if ( strPtr = = addr + origMaxLength )
wasTerminated = true ;
if ( valString . length ( ) = = formatInfo . mOverrideCount )
wasTerminated = true ;
// if (formatInfo.mDisplayType == DwDisplayType_Ascii)
// {
// // Our encoding for retVal is already assumed to be UTF8, so the special case here actually Ascii
// valString = UTF8Encode(ToWString(valString));
// }
if ( formatInfo . mRawString )
{
if ( ( formatInfo . mDisplayType = = DwDisplayType_Utf8 ) | | ( ! hasHighAscii ) )
return valString ;
String utf8Str ;
for ( int i = 0 ; i < ( int ) valString . length ( ) ; i + + )
{
char c = valString [ i ] ;
if ( ( uint8 ) c > = 0x80 )
{
utf8Str + = ( char ) ( 0xC0 | ( ( ( uint8 ) c & 0xFF ) > > 6 ) ) ;
utf8Str + = ( char ) ( 0x80 | ( ( uint8 ) c & 0x3F ) ) ;
}
else
utf8Str + = c ;
}
return utf8Str ;
}
if ( ( readFailed ) & & ( valString . IsEmpty ( ) ) )
return " < Failed to read string > " ;
retVal + = SlashString ( valString , true , true , true ) ;
// We could go over 'maxShowSize' if we have a lot of slashed chars. An uninitialized string can be filled with '\xcc' chars
if ( ( ! formatInfo . mRawString ) & & ( ( int ) retVal . length ( ) > maxShowSize ) )
{
retVal = retVal . Substring ( 0 , maxShowSize ) ;
wasTerminated = false ;
}
if ( wasTerminated )
retVal + = " \" " ;
else
retVal + = " ... " ;
return retVal ;
}
void CeDebugger : : ProcessEvalString ( BfTypedValue useTypedValue , String & evalStr , String & displayString , CeFormatInfo & formatInfo , DebugVisualizerEntry * debugVis , bool limitLength )
{
for ( int i = 0 ; i < ( int ) evalStr . length ( ) ; i + + )
{
char c = evalStr [ i ] ;
char nextC = 0 ;
if ( i < ( int ) evalStr . length ( ) - 1 )
nextC = evalStr [ i + 1 ] ;
if ( ( c = = ' { ' ) & & ( nextC ! = ' { ' ) )
{
// Evaluate
int endIdx = i ;
for ( ; endIdx < ( int ) evalStr . length ( ) ; endIdx + + )
{
//TODO: Do better parsing - this paren could be inside a string, for example
if ( evalStr [ endIdx ] = = ' } ' )
break ;
}
CeFormatInfo displayStrFormatInfo = formatInfo ;
displayStrFormatInfo . mTotalSummaryLength = formatInfo . mTotalSummaryLength + ( int ) displayString . length ( ) ;
displayStrFormatInfo . mHidePointers = false ;
if ( ( limitLength ) & & ( displayStrFormatInfo . mTotalSummaryLength > 255 ) )
{
displayString + = " ... " ;
}
else
{
String evalString = evalStr . Substring ( i + 1 , endIdx - i - 1 ) ;
String errors ;
BfTypedValue evalResult = EvaluateInContext ( useTypedValue , evalString , & displayStrFormatInfo , NULL , & errors ) ;
if ( evalResult )
{
if ( displayStrFormatInfo . mNoEdit )
formatInfo . mNoEdit = true ;
String result = TypedValueToString ( evalResult , evalString , displayStrFormatInfo , NULL ) ;
if ( ( formatInfo . mRawString ) & & ( limitLength ) )
{
displayString = result ;
return ;
}
int crPos = ( int ) result . IndexOf ( ' \n ' ) ;
if ( crPos ! = - 1 )
displayString + = result . Substring ( 0 , crPos ) ;
else
displayString + = result ;
}
else if ( debugVis ! = NULL )
{
displayString + = " <DbgVis Failed> " ;
DbgVisFailed ( debugVis , evalString , errors ) ;
}
else
{
displayString + = " <Eval Failed> " ;
}
}
i = endIdx ;
continue ;
}
else if ( ( c = = ' { ' ) & & ( nextC = = ' { ' ) )
{
// Skip next paren
i + + ;
}
else if ( ( c = = ' } ' ) & & ( nextC = = ' } ' ) )
{
// Skip next paren
i + + ;
}
displayString + = c ;
}
}
2022-03-15 16:33:30 -07:00
String CeDebugger : : TypedValueToString ( const BfTypedValue & origTypedValue , const StringImpl & expr , CeFormatInfo & formatInfo , bool fullPrecision , CeTypeModKind typeModKind )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
BfTypedValue typedValue = origTypedValue ;
2022-03-08 06:27:06 -08:00
auto module = mCeMachine - > mCeModule ;
String retVal ;
if ( typedValue . IsNoValueType ( ) )
{
2022-03-15 16:33:30 -07:00
String typeName = TypeToString ( typedValue ) ;
retVal + = typeName ;
2022-03-08 06:27:06 -08:00
retVal + = " \n " ;
2022-03-15 16:33:30 -07:00
retVal + = typeName ;
2022-03-08 06:27:06 -08:00
retVal + = " \n " ;
retVal + = GetMemberList ( typedValue . mType , 0 , 0 , true ) ;
return retVal ;
}
auto constant = module - > mBfIRBuilder - > GetConstant ( typedValue . mValue ) ;
auto ceContext = mCeMachine - > mCurContext ;
if ( constant = = NULL )
{
return " !Invalid expression " ;
}
bool didAlloc = false ;
addr_ce addr = 0 ;
defer (
{
if ( didAlloc )
mCurDbgState - > mCeContext - > CeFree ( addr ) ;
}
) ;
if ( constant - > mConstType = = BfConstType_AggCE )
{
auto aggCE = ( BfConstantAggCE * ) constant ;
addr = aggCE - > mCEAddr ;
}
else if ( ( typedValue . IsAddr ( ) ) | | ( typedValue . mType - > IsObjectOrInterface ( ) ) | | ( typedValue . mType - > IsPointer ( ) ) )
{
2022-03-15 16:33:30 -07:00
CeTypedValue typedVal = GetAddr ( constant , typedValue . mType ) ;
addr = ( addr_ce ) typedVal . mAddr ;
2022-03-08 06:27:06 -08:00
if ( ! typedVal )
{
return " !Invalid addr type " ;
}
}
else
{
int allocSize = typedValue . mType - > mSize ;
auto typeInst = typedValue . mType - > ToTypeInstance ( ) ;
if ( typeInst ! = NULL )
allocSize = typeInst - > mInstSize ;
if ( allocSize < 0 )
return " !Invalid size " ;
addr = ( addr_ce ) ( mCurDbgState - > mCeContext - > CeMalloc ( allocSize ) - mCurDbgState - > mCeContext - > mMemory . mVals ) ;
didAlloc = true ;
if ( ! mCurDbgState - > mCeContext - > WriteConstant ( mCeMachine - > mCeModule , addr , constant , typedValue . mType ) )
{
return StrFormat ( " !Failed to encode value " ) ;
}
}
DwDisplayInfo * displayInfo = GetDisplayInfo ( formatInfo . mReferenceId ) ;
char str [ 32 ] ;
String result ;
auto memStart = mCurDbgState - > mCeContext - > mMemory . mVals ;
int checkMemSize = typedValue . mType - > mSize ;
if ( typedValue . mType - > IsPointer ( ) )
checkMemSize = typedValue . mType - > GetUnderlyingType ( ) - > mSize ;
uint8 * data = ceContext - > GetMemoryPtr ( addr , checkMemSize ) ;
if ( ( addr ! = 0 ) & & ( data = = NULL ) )
2022-03-15 16:33:30 -07:00
{
if ( typedValue . mType - > IsPointer ( ) )
return EncodeDataPtr ( addr , true ) + " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
else
return " !Invalid address " ;
}
2022-03-08 06:27:06 -08:00
addr_ce dataAddr = addr ;
if ( ( typedValue . IsAddr ( ) ) & & ( typedValue . mType - > IsObjectOrInterface ( ) ) )
dataAddr = * ( addr_ce * ) data ;
if ( formatInfo . mRawString )
{
//if ((dwValueType->mTypeCode != DbgType_Struct) && (dwValueType->mTypeCode != DbgType_Class) && (dwValueType->mTypeCode != DbgType_Ptr) && (dwValueType->mTypeCode != DbgType_SizedArray))
if ( ( ! typedValue . mType - > IsPointer ( ) ) & & ( ! typedValue . mType - > IsObjectOrStruct ( ) ) & & ( ! typedValue . mType - > IsStruct ( ) ) & & ( ! typedValue . mType - > IsSizedArray ( ) ) )
return " " ;
}
auto _ShowArraySummary = [ & ] ( String & retVal , addr_ce ptrVal , int64 arraySize , BfType * innerType )
{
auto ptrType = module - > CreatePointerType ( innerType ) ;
String displayString ;
displayString + = " { " ;
for ( int idx = 0 ; idx < arraySize ; idx + + )
{
if ( formatInfo . mTotalSummaryLength + retVal . length ( ) + displayString . length ( ) > 255 )
{
displayString + = " ... " ;
break ;
}
if ( ( idx ! = 0 ) & & ( ! displayString . EndsWith ( ' { ' ) ) )
displayString + = " , " ;
CeFormatInfo displayStrFormatInfo = formatInfo ;
displayStrFormatInfo . mExpandItemDepth = 1 ;
displayStrFormatInfo . mTotalSummaryLength = formatInfo . mTotalSummaryLength + ( int ) retVal . length ( ) + ( int ) displayString . length ( ) ;
displayStrFormatInfo . mHidePointers = false ;
displayStrFormatInfo . mArrayLength = - 1 ;
// Why did we have this "na" on here? It made "void*[3]" type things show up as "{,,}"
//String evalStr = "((" + innerType->ToStringRaw(language) + "*)" + EncodeDataPtr(ptrVal, true) + StrFormat(")[%d], na", idx);
String evalStr = StrFormat ( " ((comptype(%d))(void*) " , ptrType - > mTypeId ) + EncodeDataPtr ( ptrVal , true ) + StrFormat ( " )[%lld] " , idx ) ;
BfTypedValue evalResult = EvaluateInContext ( typedValue , evalStr , & displayStrFormatInfo ) ;
String result ;
if ( evalResult )
{
result = TypedValueToString ( evalResult , evalStr , displayStrFormatInfo , NULL ) ;
int crPos = ( int ) result . IndexOf ( ' \n ' ) ;
if ( crPos ! = - 1 )
result . RemoveToEnd ( crPos ) ;
}
else
result = " ??? " ;
displayString + = result ;
}
displayString + = " } " ;
retVal + = displayString ;
} ;
if ( formatInfo . mArrayLength ! = - 1 )
{
if ( formatInfo . mRawString )
return " " ;
if ( typedValue . mType - > IsPointer ( ) )
{
auto elementType = typedValue . mType - > GetUnderlyingType ( ) ;
String retVal ;
addr_ce ptrVal = addr ;
if ( ! formatInfo . mHidePointers )
{
retVal = EncodeDataPtr ( ptrVal , true ) + " " ;
retVal + = module - > TypeToString ( elementType ) ;
retVal + = StrFormat ( " [%lld] " , ( int64 ) formatInfo . mArrayLength ) ;
}
_ShowArraySummary ( retVal , ptrVal , formatInfo . mArrayLength , elementType ) ;
String idxStr = " [{0}] " ;
2022-03-15 16:33:30 -07:00
retVal + = " \n " + TypeToString ( typedValue ) ;
2022-03-08 06:27:06 -08:00
String evalStr = StrFormat ( " ((comptype(%d))(void*) " , typedValue . mType - > mTypeId ) + EncodeDataPtr ( ptrVal , true ) + " )[{0}] " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %lld \t %d " , 0 , ( int ) BF_MAX ( formatInfo . mArrayLength , 0 ) , 10000 ) +
" \t " + idxStr + " \t " + evalStr ;
return retVal ;
}
else
{
CeFormatInfo newFormatInfo = formatInfo ;
newFormatInfo . mArrayLength = - 1 ;
String retVal = TypedValueToString ( typedValue , expr , newFormatInfo ) ;
int crPos = ( int ) retVal . IndexOf ( ' \n ' ) ;
if ( crPos ! = - 1 )
retVal = " !Array length flag not valid with this type " + retVal . Substring ( crPos ) ;
return retVal ;
}
}
2022-03-15 16:33:30 -07:00
if ( typedValue . mType - > IsRef ( ) )
{
if ( dataAddr = = 0 )
return " <null> \n " + TypeToString ( typedValue ) ;
addr = * ( addr_ce * ) data ;
dataAddr = addr ;
data = ceContext - > GetMemoryPtr ( addr , checkMemSize ) ;
if ( ( addr ! = 0 ) & & ( data = = NULL ) )
return " !Invalid address " ;
typedValue = BfTypedValue ( typedValue . mValue , typedValue . mType - > GetUnderlyingType ( ) , true ) ;
}
if ( typedValue . mType - > IsPointer ( ) )
{
//ceContext->
addr_ce ptrVal = addr ;
String retVal ;
BfType * innerType = typedValue . mType - > GetUnderlyingType ( ) ;
if ( innerType = = NULL )
return EncodeDataPtr ( ( uint32 ) ptrVal , true ) + " \n void* " ;
bool isChar = false ;
if ( innerType - > IsChar ( ) )
isChar = true ;
if ( ( isChar ) & & ( formatInfo . mArrayLength = = - 1 ) )
{
auto primType = ( BfPrimitiveType * ) innerType ;
if ( ! formatInfo . mHidePointers )
retVal = EncodeDataPtr ( ptrVal , true ) ;
int strLen = ( int ) formatInfo . mOverrideCount ;
// if (typedValue.mIsLiteral)
// {
// if (strLen == -1)
// strLen = 0x7FFFFFFF;
// if (typedValue.mDataLen > 0)
// strLen = BF_MIN(strLen, typedValue.mDataLen);
// else
// strLen = BF_MIN(strLen, strlen(typedValue.mCharPtr));
// }
SetAndRestoreValue < intptr > prevOverrideLen ( formatInfo . mOverrideCount , strLen ) ;
String strResult = ReadString ( primType - > mTypeDef - > mTypeCode , ptrVal , strLen , formatInfo ) ;
if ( formatInfo . mRawString )
return strResult ;
if ( ! strResult . IsEmpty ( ) )
{
if ( ! retVal . IsEmpty ( ) )
retVal + = " " ;
retVal + = strResult ;
}
retVal + = " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
return retVal ;
}
else if ( ( ptrVal ! = 0 ) & & ( innerType - > IsComposite ( ) ) )
{
// addr = *(addr_ce*)data;
// dataAddr = addr;
//
// data = ceContext->GetMemoryPtr(addr, checkMemSize);
// if ((addr != 0) && (data == NULL))
// return "!Invalid address";
typedValue = BfTypedValue ( typedValue . mValue , typedValue . mType - > GetUnderlyingType ( ) , true ) ;
}
else
{
if ( formatInfo . mRawString )
return " " ;
String retVal ;
if ( ! formatInfo . mHidePointers )
retVal = EncodeDataPtr ( ( uint32 ) ptrVal , true ) ;
if ( ptrVal ! = 0 )
{
BfTypedValue innerTypedVal = BfTypedValue ( module - > mBfIRBuilder - > CreateConstAggCE ( module - > mBfIRBuilder - > MapType ( innerType ) , ( addr_ce ) ptrVal ) , innerType , true ) ;
innerTypedVal . mType = innerType ;
if ( innerTypedVal )
{
CeFormatInfo defaultFormatInfo ;
defaultFormatInfo . mTotalSummaryLength = formatInfo . mTotalSummaryLength + 2 ; // Take into accout the necessary {}'s
defaultFormatInfo . mExpandItemDepth + + ;
defaultFormatInfo . mCallStackIdx = formatInfo . mCallStackIdx ;
String innerStr = TypedValueToString ( innerTypedVal , " " , defaultFormatInfo ) ;
int crIdx = ( int ) innerStr . IndexOf ( ' \n ' ) ;
if ( crIdx ! = - 1 )
{
String innerDataStr = innerStr . Substring ( 0 , crIdx ) ;
if ( ! innerDataStr . empty ( ) )
{
if ( ! retVal . empty ( ) )
retVal + = " " ;
retVal + = " { " + innerDataStr + " } " ;
}
}
else
{
retVal + = " { ??? } " ;
}
}
}
retVal + = " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
module - > PopulateType ( innerType ) ;
if ( ( ptrVal ! = 0 ) & & ( ! innerType - > IsValuelessType ( ) ) )
{
//String ptrDataStr = StrFormat("(%s)", dwValueType->ToStringRaw(language).c_str()) + EncodeDataPtr(typedValue.mPtr, true);
retVal + = " \n * \t " ;
// Why did we have this? It messed up a pointer to sized array
/*if (language == DbgLanguage_Beef)
retVal + = " this " ;
else */
retVal + = " this " ;
if ( ! formatInfo . mReferenceId . empty ( ) )
retVal + = " , refid= " + MaybeQuoteFormatInfoParam ( formatInfo . mReferenceId ) ;
retVal + = StrFormat ( " , this=%d@0x%X " , innerType - > mTypeId , ptrVal ) ;
}
retVal + = " \n :canEdit \n :editVal \t " + EncodeDataPtr ( ( uint32 ) addr , true ) ;
return retVal ;
}
}
2022-03-08 06:27:06 -08:00
if ( typedValue . mType - > IsPrimitiveType ( ) )
{
auto primType = ( BfPrimitiveType * ) typedValue . mType ;
BfTypeCode typeCode = primType - > mTypeDef - > mTypeCode ;
if ( typeCode = = BfTypeCode_IntPtr )
typeCode = ( primType - > mSize = = 8 ) ? BfTypeCode_Int64 : BfTypeCode_Int32 ;
if ( typeCode = = BfTypeCode_UIntPtr )
typeCode = ( primType - > mSize = = 8 ) ? BfTypeCode_UInt64 : BfTypeCode_UInt32 ;
switch ( typeCode )
{
2022-03-15 16:33:30 -07:00
case BfTypeCode_None :
return " \n void " ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_Boolean :
{
auto val = * ( uint8 * ) ( data ) ;
if ( val = = 0 )
2022-03-15 16:33:30 -07:00
return " false \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
2022-03-08 06:27:06 -08:00
else if ( val = = 1 )
2022-03-15 16:33:30 -07:00
return " true \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
2022-03-08 06:27:06 -08:00
else
2022-03-15 16:33:30 -07:00
return StrFormat ( " true (%d) \ n % s " , val, TypeToString(origTypedValue.mType, typeModKind).c_str()) ;
2022-03-08 06:27:06 -08:00
}
break ;
case BfTypeCode_Char8 :
{
auto val = * ( uint8 * ) ( data ) ;
if ( val ! = 0 )
{
char str [ 2 ] = { ( char ) val } ;
result = SlashString ( str , formatInfo . mDisplayType = = DwDisplayType_Utf8 , true ) ;
if ( ! IsNormalChar ( val ) )
result = StrFormat ( " '%s' (0x%02X) \n " , result . c_str ( ) , val ) ;
else
result = StrFormat ( " '%s' \n " , result . c_str ( ) ) ;
}
else
result = " ' \\ 0' \n " ;
2022-03-15 16:33:30 -07:00
return result + TypeToString ( origTypedValue . mType , typeModKind ) ;
2022-03-08 06:27:06 -08:00
}
break ;
case BfTypeCode_Char16 :
{
auto val = * ( uint16 * ) ( data ) ;
if ( val ! = 0 )
{
u8_toutf8 ( str , 8 , val ) ;
result = SlashString ( str , true , true ) ;
if ( ! IsNormalChar ( val ) )
result = StrFormat ( " '%s' (0x%02X) \n " , result . c_str ( ) , val ) ;
else
result = StrFormat ( " '%s' \n " , result . c_str ( ) ) ;
}
else
result = " ' \\ 0' \n " ;
2022-03-15 16:33:30 -07:00
return result + TypeToString ( origTypedValue . mType , typeModKind ) ;
2022-03-08 06:27:06 -08:00
}
break ;
case BfTypeCode_Char32 :
{
auto val = * ( uint32 * ) ( data ) ;
if ( val ! = 0 )
{
u8_toutf8 ( str , 8 , val ) ;
result = SlashString ( str , true , true ) ;
if ( ! IsNormalChar ( val ) )
result = StrFormat ( " '%s' (0x%02X) \n " , result . c_str ( ) , val ) ;
else
result = StrFormat ( " '%s' \n " , result . c_str ( ) ) ;
}
else
result = " ' \\ 0' \n " ;
2022-03-15 16:33:30 -07:00
return result + TypeToString ( origTypedValue . mType , typeModKind ) ;
2022-03-08 06:27:06 -08:00
}
break ;
case BfTypeCode_Int8 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < int8 > ( * ( int8 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_UInt8 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < uint8 > ( * ( uint8 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_Int16 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < int16 > ( * ( int16 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_UInt16 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < uint16 > ( * ( uint16 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_Int32 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < int32 > ( * ( int32 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_UInt32 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < uint32 > ( * ( uint32 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_Int64 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < int64 > ( * ( int64 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_UInt64 :
2022-03-15 16:33:30 -07:00
return IntTypeToString < uint64 > ( * ( uint64 * ) ( data ) , TypeToString ( origTypedValue . mType , typeModKind ) , displayInfo , formatInfo ) ;
2022-03-08 06:27:06 -08:00
case BfTypeCode_Float :
{
DwFloatDisplayType floatDisplayType = displayInfo - > mFloatDisplayType ;
if ( floatDisplayType = = DwFloatDisplayType_Default )
floatDisplayType = DwFloatDisplayType_Minimal ;
if ( floatDisplayType = = DwFloatDisplayType_Minimal )
ExactMinimalFloatToStr ( * ( float * ) data , str ) ;
else if ( floatDisplayType = = DwFloatDisplayType_Full )
sprintf ( str , " %1.9g " , * ( float * ) data ) ;
else if ( floatDisplayType = = DwFloatDisplayType_HexUpper )
sprintf ( str , " 0x%04X " , * ( uint32 * ) data ) ;
else //if (floatDisplayType == DwFloatDisplayType_HexLower)
sprintf ( str , " 0x%04x " , * ( uint32 * ) data ) ;
2022-03-15 16:33:30 -07:00
return StrFormat ( " %s \n %s " , str , TypeToString ( origTypedValue . mType , typeModKind ) . c_str ( ) ) ;
2022-03-08 06:27:06 -08:00
}
case BfTypeCode_Double :
{
DwFloatDisplayType floatDisplayType = displayInfo - > mFloatDisplayType ;
if ( floatDisplayType = = DwFloatDisplayType_Default )
floatDisplayType = DwFloatDisplayType_Minimal ;
if ( floatDisplayType = = DwFloatDisplayType_Minimal )
ExactMinimalDoubleToStr ( * ( double * ) data , str ) ;
else if ( floatDisplayType = = DwFloatDisplayType_Full )
sprintf ( str , " %1.17g " , * ( double * ) data ) ;
else if ( floatDisplayType = = DwFloatDisplayType_HexUpper )
sprintf ( str , " 0x%08llX " , * ( uint64 * ) data ) ;
else //if (floatDisplayType == DwFloatDisplayType_HexLower)
sprintf ( str , " 0x%08llx " , * ( uint64 * ) data ) ;
2022-03-15 16:33:30 -07:00
return StrFormat ( " %s \n %s " , str , TypeToString ( origTypedValue . mType , typeModKind ) . c_str ( ) ) ;
2022-03-08 06:27:06 -08:00
}
}
}
if ( typedValue . mType - > IsSizedArray ( ) )
{
auto arrayType = ( BfSizedArrayType * ) typedValue . mType ;
auto innerType = arrayType - > mElementType ;
String retVal ;
addr_ce ptrVal = addr ;
intptr arraySize = arrayType - > mElementCount ;
intptr innerSize = innerType - > GetStride ( ) ;
String idxStr = " [{0}] " ;
if ( innerType - > IsChar ( ) )
{
auto primType = ( BfPrimitiveType * ) innerType ;
String strVal = ReadString ( primType - > mTypeDef - > mTypeCode , ptrVal , arraySize , formatInfo ) ;
if ( formatInfo . mRawString )
return strVal ;
retVal + = strVal ;
}
else
{
if ( formatInfo . mRawString )
return " " ;
_ShowArraySummary ( retVal , ptrVal , arraySize , innerType ) ;
}
2022-03-15 16:33:30 -07:00
retVal + = " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
2022-03-08 06:27:06 -08:00
2022-03-15 16:33:30 -07:00
String referenceId = TypeToString ( typedValue . mType ) ;
2022-03-08 06:27:06 -08:00
String evalStr ;
// Why did we have the "na"? Do we not want to show addresses for all members?
auto ptrType = module - > CreatePointerType ( innerType ) ;
evalStr = StrFormat ( " ((comptype(%d))(void*) " , ptrType - > mTypeId ) + EncodeDataPtr ( ptrVal , true ) + " )[{0}], refid= " + MaybeQuoteFormatInfoParam ( referenceId + " .[] " ) ;
if ( typedValue . IsReadOnly ( ) )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %lld \t %d " , 0 , ( int ) BF_MAX ( arraySize , 0 ) , 10000 ) +
" \t " + idxStr + " \t " + evalStr ;
return retVal ;
}
if ( typedValue . mType - > IsEnum ( ) )
{
2022-03-17 16:56:56 -07:00
if ( formatInfo . mRawString )
return " " ;
2022-03-08 06:27:06 -08:00
String retVal ;
2022-03-17 16:56:56 -07:00
if ( typedValue . mType - > IsTypedPrimitive ( ) )
{
int64 bitsLeft = ValueToInt ( typedValue ) ;
int valueCount = 0 ;
2022-03-08 06:27:06 -08:00
2022-03-17 16:56:56 -07:00
String editVal ;
2022-03-08 06:27:06 -08:00
2022-03-17 16:56:56 -07:00
auto typeInst = typedValue . mType - > ToTypeInstance ( ) ;
auto dbgTypeInfo = GetDbgTypeInfo ( typedValue . mType - > mTypeId ) ;
2022-03-08 06:27:06 -08:00
2022-03-17 16:56:56 -07:00
while ( ( dbgTypeInfo ! = NULL ) & & ( ( bitsLeft ! = 0 ) | | ( valueCount = = 0 ) ) )
2022-03-08 06:27:06 -08:00
{
2022-03-17 16:56:56 -07:00
CeDbgTypeInfo : : ConstIntEntry * bestMatch = NULL ;
2022-03-08 06:27:06 -08:00
for ( auto & constIntEntry : dbgTypeInfo - > mConstIntEntries )
{
2022-03-17 16:56:56 -07:00
if ( constIntEntry . mVal = = bitsLeft )
2022-03-08 06:27:06 -08:00
{
bestMatch = & constIntEntry ;
break ;
}
}
2022-03-17 16:56:56 -07:00
if ( bestMatch = = NULL )
{
for ( auto & constIntEntry : dbgTypeInfo - > mConstIntEntries )
{
if ( ( constIntEntry . mVal ! = 0 ) & &
( ( constIntEntry . mVal & bitsLeft ) = = constIntEntry . mVal ) )
{
bestMatch = & constIntEntry ;
break ;
}
}
}
if ( bestMatch = = NULL )
break ;
if ( valueCount > 0 )
{
retVal + = " | " ;
}
auto bestFieldInstance = & typeInst - > mFieldInstances [ bestMatch - > mFieldIdx ] ;
retVal + = " . " ;
retVal + = bestFieldInstance - > GetFieldDef ( ) - > mName ;
2022-03-08 06:27:06 -08:00
2022-03-17 16:56:56 -07:00
valueCount + + ;
bitsLeft & = ~ bestMatch - > mVal ;
}
if ( ( valueCount = = 0 ) | | ( bitsLeft ! = 0 ) )
2022-03-08 06:27:06 -08:00
{
2022-03-17 16:56:56 -07:00
if ( valueCount > 0 )
retVal + = " | " ;
retVal + = StrFormat ( " %lld " , bitsLeft ) ;
2022-03-08 06:27:06 -08:00
}
2022-03-17 16:56:56 -07:00
retVal + = " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
retVal + = " \n :canEdit " ;
2022-03-08 06:27:06 -08:00
2022-03-17 16:56:56 -07:00
return retVal ;
2022-03-08 06:27:06 -08:00
}
2022-03-17 16:56:56 -07:00
else if ( typedValue . mType - > mDefineState > = BfTypeDefineState_Defined )
2022-03-08 06:27:06 -08:00
{
2022-03-17 16:56:56 -07:00
auto typeInst = typedValue . mType - > ToTypeInstance ( ) ;
BfType * dscrType = typeInst - > GetDiscriminatorType ( ) ;
BfType * payloadType = typeInst - > GetUnionInnerType ( ) ;
2022-03-08 06:27:06 -08:00
2022-03-17 16:56:56 -07:00
int dscrOffset = BF_ALIGN ( payloadType - > mSize , dscrType - > mAlign ) ;
2022-03-08 06:27:06 -08:00
2022-03-17 16:56:56 -07:00
int dscrVal = 0 ;
memcpy ( & dscrVal , data + dscrOffset , dscrType - > mSize ) ;
for ( auto & fieldInstance : typeInst - > mFieldInstances )
{
auto fieldDef = fieldInstance . GetFieldDef ( ) ;
if ( ! fieldInstance . mIsEnumPayloadCase )
continue ;
int tagId = - fieldInstance . mDataIdx - 1 ;
if ( dscrVal = = tagId )
{
auto evalResult = BfTypedValue ( module - > mBfIRBuilder - > CreateConstAggCE (
module - > mBfIRBuilder - > MapType ( fieldInstance . mResolvedType ) , ( addr_ce ) dataAddr ) , fieldInstance . mResolvedType , true ) ;
String innerResult = TypedValueToString ( evalResult , " " , formatInfo , NULL ) ;
int crPos = ( int ) innerResult . IndexOf ( ' \n ' ) ;
if ( crPos ! = - 1 )
innerResult . RemoveToEnd ( crPos ) ;
retVal + = " . " ;
retVal + = fieldDef - > mName ;
retVal + = innerResult ;
retVal + = " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
retVal + = " \n :canEdit " ;
retVal + = " \n " + GetMemberList ( fieldInstance . mResolvedType , addr , dataAddr , false ) ;
return retVal ;
}
}
}
2022-03-08 06:27:06 -08:00
}
if ( typedValue . mType - > IsTypedPrimitive ( ) )
{
auto innerType = typedValue . mType - > GetUnderlyingType ( ) ;
BfTypedValue innerTypedVal = typedValue ;
innerTypedVal . mType = innerType ;
auto innerReturn = TypedValueToString ( innerTypedVal , expr , formatInfo , fullPrecision ) ;
if ( innerReturn . StartsWith ( " ! " ) )
return innerReturn ;
int crPos = ( int ) innerReturn . IndexOf ( ' \n ' ) ;
if ( crPos = = - 1 )
return innerReturn ;
retVal + = " { " ;
retVal + = innerReturn . Substring ( 0 , crPos ) ;
retVal + = " } " ;
2022-03-15 16:33:30 -07:00
retVal + = " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
2022-03-08 06:27:06 -08:00
return retVal ;
}
bool isCompositeType = typedValue . mType - > IsStruct ( ) | | typedValue . mType - > IsObject ( ) ;
if ( isCompositeType )
{
BfTypeInstance * displayType = typedValue . mType - > ToTypeInstance ( ) ;
bool isMemoryValid = true ;
if ( ( dataAddr = = 0 ) & & ( addr ! = 0 ) )
dataAddr = * ( addr_ce * ) data ;
2022-03-15 16:33:30 -07:00
if ( ( ( ( origTypedValue . mType - > IsObjectOrInterface ( ) ) | | ( origTypedValue . mType - > IsPointer ( ) ) ) & &
2022-03-08 06:27:06 -08:00
( ! formatInfo . mHidePointers ) | | ( dataAddr = = 0 ) ) )
{
retVal = EncodeDataPtr ( ( uint32 ) dataAddr , true ) ;
retVal + = " " ;
if ( ! ceContext - > CheckMemory ( dataAddr , displayType - > mInstSize ) )
isMemoryValid = false ;
}
bool isBadSrc = false ;
bool isNull = dataAddr = = 0 ;
bool hadCustomDisplayString = false ;
BfTypeInstance * actualType = displayType ;
bool useActualRawType = false ;
bool isTuple = typedValue . mType - > IsTuple ( ) ;
String ptrDataStr ;
if ( ! formatInfo . mIgnoreDerivedClassInfo )
{
if ( actualType - > IsObject ( ) )
{
if ( dataAddr ! = 0 )
{
uint8 * dataPtr = ceContext - > GetMemoryPtr ( dataAddr , 4 ) ;
if ( dataPtr = = 0 )
return " !Invalid object address " ;
int actualTypeid = * ( int32 * ) dataPtr ;
auto checkType = mCompiler - > mContext - > FindTypeById ( actualTypeid ) ;
if ( checkType ! = NULL )
actualType = checkType - > ToTypeInstance ( ) ;
}
}
}
2022-03-15 16:33:30 -07:00
BfTypedValue summaryTypedValue = typedValue ;
if ( ( actualType ! = NULL ) & & ( actualType ! = displayType ) )
{
summaryTypedValue = BfTypedValue ( module - > mBfIRBuilder - > CreateIntToPtr ( addr , module - > mBfIRBuilder - > MapType ( actualType ) ) , actualType ) ;
}
2022-03-08 06:27:06 -08:00
DebugVisualizerEntry * debugVis = NULL ;
Array < String > dbgVisWildcardCaptures ;
if ( ( ! formatInfo . mNoVisualizers ) & & ( ! isNull ) & & ( ! isBadSrc ) )
{
2022-03-15 16:33:30 -07:00
debugVis = FindVisualizerForType ( summaryTypedValue . mType , & dbgVisWildcardCaptures ) ;
2022-03-08 06:27:06 -08:00
}
bool wantsCustomExpandedItems = false ;
String displayString ;
if ( debugVis ! = NULL )
{
auto & displayStringList = formatInfo . mRawString ? debugVis - > mStringViews : debugVis - > mDisplayStrings ;
for ( auto displayEntry : displayStringList )
{
if ( ! displayEntry - > mCondition . empty ( ) )
{
2022-03-15 16:33:30 -07:00
if ( ! EvalCondition ( debugVis , summaryTypedValue , formatInfo , displayEntry - > mCondition , dbgVisWildcardCaptures , displayString ) )
2022-03-08 06:27:06 -08:00
continue ;
}
hadCustomDisplayString = true ;
String displayStr = mDebugManager - > mDebugVisualizers - > DoStringReplace ( displayEntry - > mString , dbgVisWildcardCaptures ) ;
if ( displayString . length ( ) > 0 )
displayString + = " " ;
2022-03-15 16:33:30 -07:00
ProcessEvalString ( summaryTypedValue , displayStr , displayString , formatInfo , debugVis , true ) ;
2022-03-08 06:27:06 -08:00
if ( formatInfo . mRawString )
return displayString ;
break ;
}
if ( ( ! debugVis - > mExpandItems . empty ( ) ) | | ( debugVis - > mCollectionType ! = DebugVisualizerEntry : : CollectionType_None ) )
{
wantsCustomExpandedItems = true ;
}
}
if ( formatInfo . mRawString )
return " " ;
2022-03-17 17:04:32 -07:00
String reflectedTypeName ;
if ( displayType - > IsInstanceOf ( mCompiler - > mTypeTypeDef ) )
{
auto typeInst = displayType - > ToTypeInstance ( ) ;
auto typeIdField = typeInst - > mTypeDef - > GetFieldByName ( " mTypeId " ) ;
if ( typeIdField ! = NULL )
{
auto & fieldInstance = typeInst - > mFieldInstances [ typeIdField - > mIdx ] ;
int typeId = 0 ;
memcpy ( & typeId , data + fieldInstance . mDataOffset , fieldInstance . mResolvedType - > mSize ) ;
auto typeType = mCompiler - > mContext - > FindTypeById ( typeId ) ;
if ( typeType ! = NULL )
reflectedTypeName = module - > TypeToString ( typeType ) ;
}
}
if ( ! reflectedTypeName . IsEmpty ( ) )
{
displayString + = " { " ;
displayString + = reflectedTypeName ;
displayString + = " } " ;
}
else if ( ( ! isNull ) & & ( ! formatInfo . mNoVisualizers ) & & ( ! hadCustomDisplayString ) )
2022-03-08 06:27:06 -08:00
{
// Create our own custom display
String firstRet ;
String bigRet = isTuple ? " ( " : " { " ;
int memberIdx = 0 ;
2022-03-15 16:33:30 -07:00
BfType * summaryType = summaryTypedValue . mType ;
2022-03-08 06:27:06 -08:00
bool summaryDone = false ;
bool truncatedMemberList = false ;
2022-03-15 16:33:30 -07:00
2022-03-08 06:27:06 -08:00
String summaryDataStr = ptrDataStr ;
String splatStr ;
if ( dataAddr = = - 1 )
splatStr = expr ;
while ( ( summaryType ! = NULL ) & & ( isMemoryValid ) )
{
if ( ( summaryType - > IsTypedPrimitive ( ) )
//&& ((summaryType->mBaseTypes.IsEmpty()) || (!summaryType->mBaseTypes.front()->mBaseType->IsTypedPrimitive())))
)
{
if ( formatInfo . mTotalSummaryLength + ( int ) displayString . length ( ) > 255 )
{
truncatedMemberList = true ;
summaryDone = true ;
bigRet + = " ... " ;
}
else
{
CeFormatInfo displayStrFormatInfo = formatInfo ;
displayStrFormatInfo . mExpandItemDepth = 1 ;
displayStrFormatInfo . mTotalSummaryLength + = ( int ) displayString . length ( ) ;
displayStrFormatInfo . mHidePointers = false ;
BfType * primType = summaryType - > GetUnderlyingType ( ) ;
String result ;
if ( primType - > IsInteger ( ) )
formatInfo . mTypeKindFlags = ( DbgTypeKindFlags ) ( formatInfo . mTypeKindFlags | DbgTypeKindFlag_Int ) ;
if ( ( dataAddr ! = 0 ) & & ( dataAddr ! = - 1 ) )
{
//String evalString = "(" + primType->ToString() + ")" + ptrDataStr;
// BfTypedValue evalResult = EvaluateInContext(dbgCompileUnit, origTypedValue, evalString, &displayStrFormatInfo);
// if (evalResult)
// result = TypedValueToString(evalResult, evalString, displayStrFormatInfo, NULL);
}
else
{
// BfTypedValue evalResult = origTypedValue;
// evalResult.mType = primType;
// String evalString = "(" + primType->ToString() + ")" + expr;
// result = TypedValueToString(evalResult, evalString, displayStrFormatInfo, NULL);
}
if ( formatInfo . mRawString )
return result ;
int crPos = ( int ) result . IndexOf ( ' \n ' ) ;
if ( crPos ! = - 1 )
result . RemoveToEnd ( crPos ) ;
if ( memberIdx = = 0 )
firstRet = result ;
bigRet + = result ;
memberIdx + + ;
}
}
auto summaryTypeInst = summaryType - > ToTypeInstance ( ) ;
if ( summaryTypeInst = = NULL )
break ;
module - > PopulateType ( summaryTypeInst ) ;
for ( auto & fieldInst : summaryTypeInst - > mFieldInstances )
{
auto fieldDef = fieldInst . GetFieldDef ( ) ;
2022-03-15 16:33:30 -07:00
if ( fieldDef = = NULL )
continue ;
if ( fieldInst . mResolvedType = = NULL )
continue ;
2022-03-08 06:27:06 -08:00
if ( ! fieldDef - > mIsStatic )
{
if ( formatInfo . mTotalSummaryLength + retVal . length ( ) + bigRet . length ( ) > 255 )
{
truncatedMemberList = true ;
summaryDone = true ;
bigRet + = " ... " ;
break ;
}
//if (fieldDef->mName != NULL)
{
// if (member->mName[0] == '$')
// continue;
if ( ! isdigit ( fieldDef - > mName [ 0 ] ) )
{
if ( memberIdx ! = 0 )
bigRet + = isTuple ? " , " : " " ;
if ( ( ! isTuple ) | | ( fieldDef - > mName [ 0 ] ! = ' _ ' ) )
{
bigRet + = String ( fieldDef - > mName ) ;
bigRet + = isTuple ? " : " : " = " ;
}
}
else
{
if ( memberIdx ! = 0 )
bigRet + = " , " ;
}
CeFormatInfo displayStrFormatInfo = formatInfo ;
displayStrFormatInfo . mExpandItemDepth = 1 ;
displayStrFormatInfo . mHidePointers = false ;
displayStrFormatInfo . mTotalSummaryLength = ( int ) ( formatInfo . mTotalSummaryLength + retVal . length ( ) + bigRet . length ( ) ) ;
// String evalString;
// if (dataPtr != -1)
// {
// if ((fieldDef->mName[0] >= '0') && (fieldDef->mName[0] <= '9'))
// evalString += "this.";
// evalString += String(member->mName); // +", this=" + summaryDataStr;
// }
// else
// {
// evalString = "(";
// evalString += splatStr;
// evalString += ").";
// evalString += fieldDef->mName;
// }
String referenceId ;
String result ;
if ( ! fieldInst . mResolvedType - > IsValuelessType ( ) )
{
auto addrVal = dataAddr + fieldInst . mDataOffset ;
BfTypedValue evalResult ;
if ( fieldInst . mResolvedType - > IsObjectOrInterface ( ) )
{
auto typeInst = fieldInst . mResolvedType - > ToTypeInstance ( ) ;
evalResult = BfTypedValue ( module - > mBfIRBuilder - > CreateConstAggCE ( module - > mBfIRBuilder - > MapTypeInst ( typeInst ) , ( addr_ce ) addrVal ) , typeInst , true ) ;
}
else
{
evalResult = BfTypedValue ( module - > mBfIRBuilder - > CreateConstAggCE ( module - > mBfIRBuilder - > MapType ( fieldInst . mResolvedType ) , ( addr_ce ) addrVal ) , fieldInst . mResolvedType , true ) ;
}
//BfTypedValue evalResult = EvaluateInContext(dbgCompileUnit, summaryTypedValue, evalString, &displayStrFormatInfo, &referenceId);
if ( evalResult )
{
displayStrFormatInfo . mReferenceId = referenceId ;
result = TypedValueToString ( evalResult , " " , displayStrFormatInfo , NULL ) ;
int crPos = ( int ) result . IndexOf ( ' \n ' ) ;
if ( crPos ! = - 1 )
result . RemoveToEnd ( crPos ) ;
}
else
result = " ??? " ;
}
if ( fieldInst . mResolvedType - > IsInteger ( ) )
formatInfo . mTypeKindFlags = ( DbgTypeKindFlags ) ( formatInfo . mTypeKindFlags | DbgTypeKindFlag_Int ) ;
if ( formatInfo . mRawString )
return result ;
if ( memberIdx = = 0 )
firstRet = result ;
bigRet + = result ;
//formatInfo.mEmbeddedDisplayCount = displayStrFormatInfo.mEmbeddedDisplayCount;
memberIdx + + ;
}
}
}
if ( truncatedMemberList )
break ;
// Find first base class with members
BfType * nextSummaryType = summaryTypeInst - > mBaseType ;
summaryType = nextSummaryType ;
if ( ( summaryType = = NULL ) | | ( summaryType = = module - > mContext - > mBfObjectType ) )
break ;
// If we don't have many members then find a base class with some members to show
if ( ( memberIdx ! = 0 ) & & ( displayString . length ( ) > = 255 ) )
{
truncatedMemberList = true ;
bigRet + = " ... " ;
break ;
}
}
bigRet + = isTuple ? " ) " : " } " ;
if ( displayString . length ( ) > 0 )
displayString + = " " ;
if ( ( memberIdx = = 1 ) & & ( ! truncatedMemberList ) & & ( firstRet . IndexOf ( ' { ' ) = = - 1 ) & & ( ! isTuple ) )
displayString + = " { " + firstRet + " } " ;
else
displayString + = bigRet ;
}
retVal + = displayString ;
2022-03-15 16:33:30 -07:00
retVal + = " \n " + TypeToString ( origTypedValue . mType , typeModKind ) ;
BfType * memberListType = displayType ;
2022-03-08 06:27:06 -08:00
if ( ( actualType ! = NULL ) & & ( actualType ! = displayType ) )
{
2022-03-15 16:33:30 -07:00
if ( displayType = = module - > mContext - > mBfObjectType )
{
memberListType = actualType ;
}
else
{
String actualTypeName = module - > TypeToString ( actualType ) ;
retVal + = StrFormat ( " {%s} \n [%s] \t this,this=%d@0x%X " , actualTypeName . c_str ( ) , actualTypeName . c_str ( ) , actualType - > mTypeId , addr ) ;
}
2022-03-08 06:27:06 -08:00
}
if ( formatInfo . mNoMembers )
{
//
}
else if ( wantsCustomExpandedItems )
{
2022-03-15 16:33:30 -07:00
HandleCustomExpandedItems ( retVal , debugVis , summaryTypedValue , addr , dataAddr , dbgVisWildcardCaptures , formatInfo ) ;
2022-03-08 06:27:06 -08:00
}
else if ( ( ! isNull ) & & ( ! isBadSrc ) )
{
2022-03-15 16:33:30 -07:00
retVal + = " \n " + GetMemberList ( memberListType , addr , dataAddr , false ) ;
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
if ( ( origTypedValue . mType - > IsObjectOrInterface ( ) ) | | ( origTypedValue . mType - > IsPointer ( ) ) )
2022-03-08 06:27:06 -08:00
{
retVal + = " \n :editVal \t " + EncodeDataPtr ( ( uint32 ) dataAddr , true ) ;
}
return retVal ;
}
2022-03-15 16:33:30 -07:00
return " !Failed to display value " ;
2022-03-08 06:27:06 -08:00
}
void CeDebugger : : HandleCustomExpandedItems ( String & retVal , DebugVisualizerEntry * debugVis , BfTypedValue typedValue , addr_ce addr , addr_ce addrInst , Array < String > & dbgVisWildcardCaptures , CeFormatInfo & formatInfo )
{
auto debugVisualizers = mDebugManager - > mDebugVisualizers ;
auto ceModule = mCeMachine - > mCeModule ;
if ( formatInfo . mExpandItemDepth > 10 ) // Avoid crashing on circular ExpandItems
return ;
bool isReadOnly = false ;
// if (useTypedValue.mIsReadOnly)
// isReadOnly = true;
String ptrUseDataStr = StrFormat ( " %d@0x%X " , typedValue . mType - > mTypeId , addrInst ) ;
for ( auto entry : debugVis - > mExpandItems )
{
if ( ! entry - > mCondition . empty ( ) )
{
String error ;
if ( ! EvalCondition ( debugVis , typedValue , formatInfo , entry - > mCondition , dbgVisWildcardCaptures , error ) )
{
if ( ! error . empty ( ) )
retVal + = " \n " + entry - > mName + " \t @!<DbgVis Failed>@! " ;
continue ;
}
}
String replacedStr = debugVisualizers - > DoStringReplace ( entry - > mValue , dbgVisWildcardCaptures ) ;
retVal + = " \n " + entry - > mName + " \t " + replacedStr + " , this= " + ptrUseDataStr ;
}
String referenceId = ceModule - > TypeToString ( typedValue . mType ) ;
if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_ExpandedItem )
{
BfTypedValue itemValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( itemValue )
{
CeFormatInfo itemFormatInfo = formatInfo ;
itemFormatInfo . mExpandItemDepth + + ;
String itemRetVal = TypedValueToString ( itemValue , " " , itemFormatInfo , NULL ) ;
int crIdx = ( int ) itemRetVal . IndexOf ( ' \n ' ) ;
if ( crIdx ! = - 1 )
{
crIdx = ( int ) itemRetVal . IndexOf ( ' \n ' , crIdx + 1 ) ;
if ( crIdx ! = - 1 )
retVal + = itemRetVal . Substring ( crIdx ) ;
}
}
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_Array )
{
BfTypedValue sizeValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mSize , dbgVisWildcardCaptures ) , & formatInfo ) ;
Array < int > lowerDimSizes ;
for ( auto lowerDim : debugVis - > mLowerDimSizes )
{
BfTypedValue lowerDimValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( lowerDim , dbgVisWildcardCaptures ) , & formatInfo ) ;
int dimSize = 0 ;
if ( ( lowerDimValue ) & & ( lowerDimValue . mType - > IsInteger ( ) ) )
dimSize = ( int ) ValueToInt ( lowerDimValue ) ;
dimSize = BF_MAX ( dimSize , 1 ) ;
lowerDimSizes . push_back ( dimSize ) ;
}
if ( ( sizeValue ) & & ( sizeValue . mType - > IsInteger ( ) ) & & ( ValueToInt ( sizeValue ) > 0 ) )
{
if ( ! debugVis - > mCondition . IsEmpty ( ) )
{
int size = ( int ) ValueToInt ( sizeValue ) ;
BfTypedValue headPointer = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
BfTypedValue curNode = headPointer ;
Array < addr_ce > parentList ;
String continuationData ;
int totalSize = 2 ;
auto valueType = headPointer . mType ;
String addrs = GetArrayItems ( debugVis , valueType , headPointer , totalSize , & continuationData ) ;
String firstAddr ;
String secondAddr ;
bool hasSecondAddr = valueType = = NULL ;
if ( addrs . length ( ) > 0 )
{
const char * addrsPtr = addrs . c_str ( ) ;
firstAddr = addrs . Substring ( 0 , sizeof ( addr_ce ) * 2 ) ;
if ( hasSecondAddr )
secondAddr = addrs . Substring ( sizeof ( addr_ce ) * 2 , sizeof ( addr_ce ) * 2 ) ;
}
String evalStr ;
if ( valueType ! = NULL )
{
auto ptrType = valueType ;
if ( ! valueType - > IsPointer ( ) )
ptrType = ceModule - > CreatePointerType ( valueType ) ;
evalStr = StrFormat ( " (comptype(%d) " , ptrType - > mTypeId ) ;
evalStr + = " )(void*)0x{1} " ;
}
else
{
evalStr + = " ({1})(void*)0x{2} " ;
}
if ( ! debugVis - > mShowElementAddrs )
evalStr . Insert ( 0 , " * " ) ;
if ( addrs . length ( ) > 0 )
{
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %d \t %d " , 0 , BF_MAX ( size , 0 ) , 10000 ) +
" \t [{0}] \t " + evalStr + " \t " + firstAddr ;
if ( hasSecondAddr )
retVal + = " \t " + secondAddr ;
if ( size ! = 0 )
{
retVal + = " \n :addrs \t " + addrs ;
if ( valueType = = NULL )
retVal + = " \n :addrsEntrySize \t 2 " ;
if ( continuationData . length ( ) > 0 )
retVal + = " \n :continuation \t " + continuationData ;
}
}
}
else if ( lowerDimSizes . size ( ) = = 1 )
{
int dimSize1 = lowerDimSizes [ 0 ] ;
String evalStr = " ( " + debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) +
StrFormat ( " + {0} * %d), arraysize=%d, na, this= " , dimSize1 , dimSize1 ) + ptrUseDataStr ;
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %lld \t %d " , 0 , ValueToInt ( sizeValue ) / dimSize1 , 50000 ) +
" \t [{0}] \t " + evalStr ;
}
else if ( lowerDimSizes . size ( ) = = 2 )
{
int dimSize1 = lowerDimSizes [ 0 ] ;
int dimSize2 = lowerDimSizes [ 1 ] ;
BfTypedValue headPointer = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( ( headPointer . mType ! = NULL ) & & ( headPointer . mType - > IsPointer ( ) ) )
{
String evalStr = StrFormat ( " ((%s[%d]*) " , ceModule - > TypeToString ( headPointer . mType - > GetUnderlyingType ( ) ) . c_str ( ) , dimSize2 ) + debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) +
StrFormat ( " + {0} * %d), arraysize=%d, na, this= " , dimSize1 , dimSize1 ) + ptrUseDataStr ;
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %lld \t %d " , 0 , ValueToInt ( sizeValue ) / dimSize1 / dimSize2 , 50000 ) +
" \t [{0}] \t " + evalStr ;
}
}
else if ( lowerDimSizes . size ( ) = = 3 )
{
int dimSize1 = lowerDimSizes [ 0 ] ;
int dimSize2 = lowerDimSizes [ 1 ] ;
int dimSize3 = lowerDimSizes [ 2 ] ;
BfTypedValue headPointer = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( ( headPointer . mType ! = NULL ) & & ( headPointer . mType - > IsPointer ( ) ) )
{
String evalStr = StrFormat ( " ((%s[%d][%d]*) " , ceModule - > TypeToString ( headPointer . mType - > GetUnderlyingType ( ) ) . c_str ( ) , dimSize2 , dimSize3 ) + debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) +
StrFormat ( " + {0} * %d), arraysize=%d, na, this= " , dimSize1 , dimSize1 ) + ptrUseDataStr ;
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %lld \t %d " , 0 , ValueToInt ( sizeValue ) / dimSize1 / dimSize2 / dimSize3 , 50000 ) +
" \t [{0}] \t " + evalStr ;
}
}
else
{
String evalStr = " *( " + debugVisualizers - > DoStringReplace ( debugVis - > mValuePointer , dbgVisWildcardCaptures ) + " + {0}), this= " + ptrUseDataStr ;
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %lld \t %d " , 0 , ValueToInt ( sizeValue ) , 50000 ) +
" \t [{0}] \t " + evalStr ;
}
}
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_IndexItems )
{
BfTypedValue sizeValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mSize , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( ( sizeValue ) & & ( sizeValue . mType - > IsInteger ( ) ) & & ( ValueToInt ( sizeValue ) > 0 ) )
{
String evalStr = debugVis - > mValuePointer + " , this= " + ptrUseDataStr ;
evalStr . Replace ( " $i " , " {0} " ) ;
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %lld \t %d " , 0 , ValueToInt ( sizeValue ) , 50000 ) +
" \t [{0}] \t " + evalStr ;
}
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_LinkedList )
{
BfType * valueType = NULL ;
if ( ! debugVis - > mValueType . empty ( ) )
{
valueType = FindType ( debugVisualizers - > DoStringReplace ( debugVis - > mValueType , dbgVisWildcardCaptures ) ) ;
}
BfTypedValue headPointer = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mHeadPointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( headPointer )
{
BfTypedValue endPointer ;
if ( ! debugVis - > mEndPointer . empty ( ) )
endPointer = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mEndPointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
BfTypedValue nextPointer = EvaluateInContext ( headPointer , debugVisualizers - > DoStringReplace ( debugVis - > mNextPointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
int size = - 1 ;
if ( ! debugVis - > mSize . empty ( ) )
{
auto sizeValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mSize , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( sizeValue )
size = ( int ) ValueToInt ( sizeValue ) ;
}
2022-03-15 16:33:30 -07:00
auto ceEndPointerVal = GetAddr ( endPointer ) ;
2022-03-08 06:27:06 -08:00
BfTypedValue curNode = headPointer ;
Array < addr_ce > parentList ;
String continuationData ;
int totalSize = 2 ;
2022-03-15 16:33:30 -07:00
String addrs = GetLinkedListItems ( debugVis , ( addr_ce ) ceEndPointerVal . mAddr , valueType , curNode , totalSize , & continuationData ) ;
2022-03-08 06:27:06 -08:00
String firstAddr ;
String secondAddr ;
bool hasSecondAddr = valueType = = NULL ;
if ( addrs . length ( ) > 0 )
{
const char * addrsPtr = addrs . c_str ( ) ;
firstAddr = addrs . Substring ( 0 , sizeof ( addr_ce ) * 2 ) ;
if ( hasSecondAddr )
secondAddr = addrs . Substring ( sizeof ( addr_ce ) * 2 , sizeof ( addr_ce ) * 2 ) ;
}
String evalStr ;
if ( valueType ! = NULL )
{
auto ptrType = valueType ;
if ( ! valueType - > IsPointer ( ) )
ptrType = ceModule - > CreatePointerType ( valueType ) ;
evalStr = StrFormat ( " (comptype(%d) " , ptrType - > mTypeId ) ;
evalStr + = " )0x{1} " ;
}
else
{
evalStr + = " ({1})0x{2} " ;
}
if ( ! debugVis - > mShowElementAddrs )
evalStr . Insert ( 0 , " * " ) ;
if ( addrs . length ( ) > 0 )
{
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %d \t %d " , 0 , size , 10000 ) +
" \t [{0}] \t " + evalStr + " \t " + firstAddr ;
if ( hasSecondAddr )
retVal + = " \t " + secondAddr ;
if ( size ! = 0 )
{
retVal + = " \n :addrs \t " + addrs ;
if ( valueType = = NULL )
retVal + = " \n :addrsEntrySize \t 2 " ;
if ( continuationData . length ( ) > 0 )
retVal + = " \n :continuation \t " + continuationData ;
}
}
}
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_TreeItems )
{
BfType * valueType = NULL ;
if ( ! debugVis - > mValueType . empty ( ) )
{
valueType = FindType ( debugVisualizers - > DoStringReplace ( debugVis - > mValueType , dbgVisWildcardCaptures ) ) ;
}
BfTypedValue sizeValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mSize , dbgVisWildcardCaptures ) , & formatInfo ) ;
BfTypedValue headPointer = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mHeadPointer , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( ( sizeValue ) & & ( headPointer ) & & ( sizeValue . mType - > IsInteger ( ) ) & & ( ValueToInt ( sizeValue ) > 0 ) )
{
BfTypedValue curNode = headPointer ;
Array < addr_ce > parentList ;
String continuationData ;
int getItemCount = ( int ) BF_MIN ( ValueToInt ( sizeValue ) , 32LL ) ;
2022-03-15 16:33:30 -07:00
String addrs = GetTreeItems ( debugVis , parentList , valueType , curNode , getItemCount , & continuationData ) ;
2022-03-08 06:27:06 -08:00
addr_ce firstAddr = 0 ;
addr_ce secondAddr = 0 ;
bool hasSecondAddr = valueType = = NULL ;
if ( addrs . length ( ) > 0 )
{
const char * addrsPtr = addrs . c_str ( ) ;
firstAddr = DecodeTargetDataPtr ( addrsPtr ) ;
if ( hasSecondAddr )
secondAddr = DecodeTargetDataPtr ( addrsPtr ) ;
}
String evalStr ;
if ( valueType ! = NULL )
{
auto ptrType = valueType ;
if ( ! valueType - > IsPointer ( ) )
ptrType = ceModule - > CreatePointerType ( valueType ) ;
evalStr = StrFormat ( " (comptype(%d) " , ptrType - > mTypeId ) ;
evalStr + = " )0x{1} " ; ;
}
else
{
evalStr + = " *(_T_{1}*)0x{2} " ;
}
int size = ( int ) ValueToInt ( sizeValue ) ;
if ( addrs . length ( ) = = 0 )
{
evalStr = " " ; // Failed
}
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %d \t %d " , 0 , size , 10000 ) +
" \t [{0}] \t " + evalStr + " \t " + EncodeDataPtr ( firstAddr , false ) ;
if ( hasSecondAddr )
retVal + = " \t " + EncodeDataPtr ( secondAddr , false ) ;
if ( addrs . length ( ) > 0 )
{
retVal + = " \n :addrs \t " + addrs ;
if ( continuationData . length ( ) > 0 )
retVal + = " \n :continuation \t " + continuationData ;
}
}
}
else if ( debugVis - > mCollectionType = = DebugVisualizerEntry : : CollectionType_Dictionary )
{
BfTypedValue sizeValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mSize , dbgVisWildcardCaptures ) , & formatInfo ) ;
BfTypedValue entriesPtrValue = EvaluateInContext ( typedValue , debugVisualizers - > DoStringReplace ( debugVis - > mEntries , dbgVisWildcardCaptures ) , & formatInfo ) ;
if ( ( sizeValue ) & & ( entriesPtrValue ) & & ( sizeValue . mType - > IsInteger ( ) ) & & ( ValueToInt ( sizeValue ) > 0 ) )
{
String continuationData ;
BfType * valueType = entriesPtrValue . mType ;
int getItemCount = ( int ) BF_MIN ( ValueToInt ( sizeValue ) , 2LL ) ;
BfType * useTypedValType = typedValue . mType ;
2022-03-15 16:33:30 -07:00
String addrs = GetDictionaryItems ( debugVis , typedValue , 0 , - 1 , getItemCount , & continuationData ) ;
2022-03-08 06:27:06 -08:00
addr_ce firstAddr = 0 ;
if ( addrs . length ( ) > 0 )
{
const char * addrsPtr = addrs . c_str ( ) ;
firstAddr = DecodeTargetDataPtr ( addrsPtr ) ;
}
2022-03-15 16:33:30 -07:00
String evalStr = " ((comptype( " + StrFormat ( " %d " , valueType - > mTypeId ) + " ))(void*)0x{1}), na " ;
2022-03-08 06:27:06 -08:00
evalStr + = " , refid= \" " + referenceId + " .[] \" " ;
if ( isReadOnly )
evalStr + = " , ne " ;
retVal + = " \n :repeat " + StrFormat ( " \t %d \t %d \t %d " , 0 , ( int ) ValueToInt ( sizeValue ) , 10000 ) +
" \t [{0}] \t " + evalStr + " \t " + EncodeDataPtr ( firstAddr , false ) ;
if ( addrs . length ( ) > 0 )
{
retVal + = " \n :addrs \t " + addrs ;
if ( continuationData . length ( ) > 0 )
retVal + = " \n :continuation \t " + continuationData ;
}
}
}
if ( formatInfo . mExpandItemDepth = = 0 )
{
retVal + = " \n [Raw View] \t this,this= " + ptrUseDataStr + " , nv " ;
}
}
String CeDebugger : : Evaluate ( const StringImpl & expr , int callStackIdx , int cursorPos , int language , DwEvalExpressionFlags expressionFlags )
{
CeFormatInfo formatInfo ;
return Evaluate ( expr , formatInfo , callStackIdx , cursorPos , language , expressionFlags ) ;
}
String CeDebugger : : EvaluateContinue ( )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
if ( mDebugPendingExpr = = NULL )
return " " ;
if ( ! mDebugPendingExpr - > mDone )
return " !pending " ;
String result = mDebugPendingExpr - > mResult ;
delete mDebugPendingExpr ;
mDebugPendingExpr = NULL ;
return result ;
2022-03-08 06:27:06 -08:00
}
void CeDebugger : : EvaluateContinueKeep ( )
{
}
String CeDebugger : : EvaluateToAddress ( const StringImpl & expr , int callStackIdx , int cursorPos )
{
return String ( ) ;
}
String CeDebugger : : EvaluateAtAddress ( const StringImpl & expr , intptr atAddr , int cursorPos )
{
return String ( ) ;
}
String CeDebugger : : GetAutoExpressions ( int callStackIdx , uint64 memoryRangeStart , uint64 memoryRangeLen )
{
return String ( ) ;
}
String CeDebugger : : GetAutoLocals ( int callStackIdx , bool showRegs )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
if ( ! mCeMachine - > mDbgPaused )
return " " ;
2022-03-08 06:27:06 -08:00
String result ;
2022-03-17 08:47:34 -07:00
auto ceFrame = GetFrame ( callStackIdx ) ;
if ( ceFrame = = NULL )
return result ;
2022-03-15 16:33:30 -07:00
int scopeIdx = - 1 ;
auto ceEntry = ceFrame - > mFunction - > FindEmitEntry ( ceFrame - > GetInstIdx ( ) ) ;
if ( ceEntry ! = NULL )
scopeIdx = ceEntry - > mScope ;
2022-03-17 08:47:34 -07:00
int instIdx = ceFrame - > GetInstIdx ( ) ;
if ( ceFrame - > mFunction - > mDbgInfo ! = NULL )
2022-03-08 06:27:06 -08:00
{
2022-03-17 08:47:34 -07:00
auto ceFunction = ceFrame - > mFunction ;
struct CeDbgInfo
2022-03-08 06:27:06 -08:00
{
2022-03-17 08:47:34 -07:00
int mShadowCount ;
int mPrevShadowIdx ;
bool mIncluded ;
CeDbgInfo ( )
{
mShadowCount = 0 ;
mPrevShadowIdx = - 1 ;
mIncluded = true ;
}
} ;
Array < CeDbgInfo > dbgInfo ;
Dictionary < String , int > nameIndices ;
dbgInfo . Resize ( ceFunction - > mDbgInfo - > mVariables . mSize ) ;
for ( int i = 0 ; i < ceFunction - > mDbgInfo - > mVariables . mSize ; i + + )
{
auto & dbgVar = ceFunction - > mDbgInfo - > mVariables [ i ] ;
if ( ( dbgVar . mScope = = scopeIdx ) & & ( instIdx > = dbgVar . mStartCodePos ) & & ( instIdx < dbgVar . mEndCodePos ) )
{
int * idxPtr = NULL ;
if ( ! nameIndices . TryAdd ( dbgVar . mName , NULL , & idxPtr ) )
2022-03-15 16:33:30 -07:00
{
2022-03-17 08:47:34 -07:00
int checkIdx = * idxPtr ;
dbgInfo [ i ] . mPrevShadowIdx = checkIdx ;
while ( checkIdx ! = - 1 )
{
dbgInfo [ checkIdx ] . mShadowCount + + ;
checkIdx = dbgInfo [ checkIdx ] . mPrevShadowIdx ;
}
2022-03-15 16:33:30 -07:00
}
2022-03-17 08:47:34 -07:00
* idxPtr = i ;
2022-03-08 06:27:06 -08:00
}
2022-03-17 08:47:34 -07:00
else
{
dbgInfo [ i ] . mIncluded = false ;
}
2022-03-08 06:27:06 -08:00
}
2022-03-17 08:47:34 -07:00
for ( int i = 0 ; i < ceFunction - > mDbgInfo - > mVariables . mSize ; i + + )
{
auto & dbgVar = ceFunction - > mDbgInfo - > mVariables [ i ] ;
if ( dbgInfo [ i ] . mIncluded )
{
for ( int shadowIdx = 0 ; shadowIdx < dbgInfo [ i ] . mShadowCount ; shadowIdx + + )
result + = " @ " ;
result + = dbgVar . mName ;
result + = " \n " ;
}
}
}
2022-03-08 06:27:06 -08:00
return result ;
}
String CeDebugger : : CompactChildExpression ( const StringImpl & expr , const StringImpl & parentExpr , int callStackIdx )
{
return String ( ) ;
}
String CeDebugger : : GetProcessInfo ( )
{
return String ( ) ;
}
DebugVisualizerEntry * CeDebugger : : FindVisualizerForType ( BfType * dbgType , Array < String > * wildcardCaptures )
{
auto ceModule = mCeMachine - > mCeModule ;
ceModule - > PopulateType ( dbgType ) ;
auto entry = mDebugManager - > mDebugVisualizers - > FindEntryForType ( ceModule - > TypeToString ( dbgType ) , DbgFlavor_Unknown , wildcardCaptures ) ;
if ( entry = = NULL )
{
auto typeInst = dbgType - > ToTypeInstance ( ) ;
if ( ( typeInst ! = NULL ) & & ( typeInst - > mBaseType ! = NULL ) )
entry = FindVisualizerForType ( typeInst - > mBaseType , wildcardCaptures ) ;
}
return entry ;
}
String CeDebugger : : GetThreadInfo ( )
{
return String ( ) ;
}
void CeDebugger : : SetActiveThread ( int threadId )
{
}
int CeDebugger : : GetActiveThread ( )
{
return 0 ;
}
void CeDebugger : : FreezeThread ( int threadId )
{
}
void CeDebugger : : ThawThread ( int threadId )
{
}
bool CeDebugger : : IsActiveThreadWaiting ( )
{
return false ;
}
void CeDebugger : : ClearCallStack ( )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
mDbgCallStack . Clear ( ) ;
2022-03-08 06:27:06 -08:00
}
void CeDebugger : : UpdateCallStack ( bool slowEarlyOut )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
if ( ! mDbgCallStack . IsEmpty ( ) )
return ;
auto ceContext = mCeMachine - > mCurContext ;
for ( int frameIdx = ceContext - > mCallStack . mSize - 1 ; frameIdx > = 0 ; frameIdx - - )
{
auto ceFrame = & ceContext - > mCallStack [ frameIdx ] ;
auto instIdx = ceFrame - > GetInstIdx ( ) ;
auto emitEntry = ceFrame - > mFunction - > FindEmitEntry ( instIdx ) ;
if ( emitEntry = = NULL )
continue ;
int scopeIdx = emitEntry - > mScope ;
int prevInlineIdx = - 1 ;
while ( scopeIdx ! = - 1 )
{
CeDbgStackInfo ceDbgStackInfo ;
ceDbgStackInfo . mFrameIdx = frameIdx ;
ceDbgStackInfo . mScopeIdx = scopeIdx ;
ceDbgStackInfo . mInlinedFrom = prevInlineIdx ;
mDbgCallStack . Add ( ceDbgStackInfo ) ;
auto ceScope = & ceFrame - > mFunction - > mDbgScopes [ scopeIdx ] ;
if ( ceScope - > mInlinedAt = = - 1 )
break ;
auto inlineInfo = & ceFrame - > mFunction - > mDbgInlineTable [ ceScope - > mInlinedAt ] ;
scopeIdx = inlineInfo - > mScope ;
prevInlineIdx = ceScope - > mInlinedAt ;
}
}
2022-03-17 08:47:34 -07:00
CeDbgStackInfo ceDbgStackInfo ;
ceDbgStackInfo . mFrameIdx = - 1 ;
ceDbgStackInfo . mScopeIdx = - 1 ;
ceDbgStackInfo . mInlinedFrom = - 1 ;
mDbgCallStack . Add ( ceDbgStackInfo ) ;
2022-03-08 06:27:06 -08:00
}
int CeDebugger : : GetCallStackCount ( )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mCeMachine - > mCritSect ) ;
if ( ! mCeMachine - > mDbgPaused )
2022-03-08 06:27:06 -08:00
return 0 ;
2022-03-15 16:33:30 -07:00
UpdateCallStack ( ) ;
return mDbgCallStack . mSize ;
2022-03-08 06:27:06 -08:00
}
int CeDebugger : : GetRequestedStackFrameIdx ( )
{
2022-03-15 16:33:30 -07:00
return mPendingActiveFrameOffset ;
2022-03-08 06:27:06 -08:00
}
int CeDebugger : : GetBreakStackFrameIdx ( )
{
return 0 ;
}
bool CeDebugger : : ReadMemory ( intptr address , uint64 length , void * dest , bool local )
{
auto ceContext = mCeMachine - > mCurContext ;
if ( ceContext = = NULL )
return false ;
auto ptr = ceContext - > GetMemoryPtr ( ( addr_ce ) address , ( int32 ) length ) ;
if ( ptr = = NULL )
return false ;
memcpy ( dest , ptr , length ) ;
return true ;
}
bool CeDebugger : : WriteMemory ( intptr address , void * src , uint64 length )
{
auto ceContext = mCeMachine - > mCurContext ;
if ( ceContext = = NULL )
return false ;
auto ptr = ceContext - > GetMemoryPtr ( ( addr_ce ) address , ( int32 ) length ) ;
if ( ptr = = NULL )
return false ;
memcpy ( ptr , src , length ) ;
return true ;
}
DbgMemoryFlags CeDebugger : : GetMemoryFlags ( intptr address )
{
return ( DbgMemoryFlags ) ( DbgMemoryFlags_Read | DbgMemoryFlags_Write ) ;
}
void CeDebugger : : UpdateRegisterUsage ( int stackFrameIdx )
{
}
void CeDebugger : : UpdateCallStackMethod ( int stackFrameIdx )
{
}
void CeDebugger : : GetCodeAddrInfo ( intptr addr , String * outFile , int * outHotIdx , int * outDefLineStart , int * outDefLineEnd , int * outLine , int * outColumn )
{
}
void CeDebugger : : GetStackAllocInfo ( intptr addr , int * outThreadId , int * outStackIdx )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
2022-03-08 06:27:06 -08:00
* outThreadId = 0 ;
if ( outStackIdx ! = NULL )
* outStackIdx = - 1 ;
2022-03-15 16:33:30 -07:00
if ( ! mCeMachine - > mDbgPaused )
return ;
2022-03-08 06:27:06 -08:00
auto ceContext = mCeMachine - > mCurContext ;
for ( int i = 0 ; i < ( int ) ceContext - > mCallStack . mSize ; i + + )
{
auto ceFrame = & ceContext - > mCallStack [ i ] ;
if ( ( addr_ce ) addr > ceFrame - > mFrameAddr )
{
if ( outStackIdx ! = NULL )
* outStackIdx = ( int ) ceContext - > mCallStack . mSize - i - 1 ;
}
}
}
String CeDebugger : : GetStackFrameInfo ( int stackFrameIdx , intptr * addr , String * outFile , int32 * outHotIdx , int32 * outDefLineStart , int32 * outDefLineEnd , int32 * outLine , int32 * outColumn , int32 * outLanguage , int32 * outStackSize , int8 * outFlags )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
if ( ! mCeMachine - > mDbgPaused )
return " " ;
UpdateCallStack ( ) ;
2022-03-08 06:27:06 -08:00
enum FrameFlags
{
FrameFlags_Optimized = 1 ,
FrameFlags_HasPendingDebugInfo = 2 ,
FrameFlags_CanGetOldSource = 4 ,
FrameFlags_WasHotReplaced = 8 ,
FrameFlags_HadError = 0x10
} ;
2022-03-15 16:33:30 -07:00
auto ceContext = mCeMachine - > mCurContext ;
2022-03-08 06:27:06 -08:00
* addr = 0 ;
* outFile = " " ;
* outHotIdx = 0 ;
* outDefLineStart = - 1 ;
* outDefLineEnd = - 1 ;
* outLine = - 1 ;
* outColumn = 0 ;
* outLanguage = DbgLanguage_Beef ;
* outStackSize = 0 ;
* outFlags = 0 ;
2022-03-15 16:33:30 -07:00
if ( ceContext = = NULL )
return " " ;
auto & dbgCallstackInfo = mDbgCallStack [ stackFrameIdx ] ;
2022-03-17 08:47:34 -07:00
if ( dbgCallstackInfo . mFrameIdx = = - 1 )
{
if ( ceContext - > mCurCallSource ! = NULL )
{
int line = - 1 ;
int lineChar = - 1 ;
auto parserData = ceContext - > mCurCallSource - > mRefNode - > GetParserData ( ) ;
if ( parserData ! = NULL )
{
parserData - > GetLineCharAtIdx ( ceContext - > mCurCallSource - > mRefNode - > GetSrcStart ( ) , line , lineChar ) ;
* outLine = line ;
* outColumn = lineChar ;
* outFile = parserData - > mFileName ;
}
}
// Entry marker
String result = " const eval " ;
if ( ceContext - > mCurCallSource - > mKind = = CeCallSource : : Kind_FieldInit )
{
return String ( " field init of : " ) + ceContext - > mCurModule - > TypeToString ( ceContext - > mCurCallSource - > mFieldInstance - > mOwner ) + " . " +
ceContext - > mCurCallSource - > mFieldInstance - > GetFieldDef ( ) - > mName ;
}
else if ( ceContext - > mCurCallSource - > mKind = = CeCallSource : : Kind_MethodInit )
{
return ( " method init of : " ) + ceContext - > mCurModule - > MethodToString ( ceContext - > mCallerMethodInstance ) ;
}
else if ( ceContext - > mCurCallSource - > mKind = = CeCallSource : : Kind_TypeInit )
result = " type init " ;
else if ( ceContext - > mCurCallSource - > mKind = = CeCallSource : : Kind_TypeDone )
result = " type done " ;
if ( ceContext - > mCallerMethodInstance ! = NULL )
result + = String ( " in : " ) + ceContext - > mCurModule - > MethodToString ( ceContext - > mCallerMethodInstance ) ;
else if ( ceContext - > mCallerTypeInstance ! = NULL )
result + = String ( " in : " ) + ceContext - > mCurModule - > TypeToString ( ceContext - > mCallerTypeInstance ) ;
return result ;
}
2022-03-15 16:33:30 -07:00
auto ceFrame = & ceContext - > mCallStack [ dbgCallstackInfo . mFrameIdx ] ;
auto ceFunction = ceFrame - > mFunction ;
2022-03-08 06:27:06 -08:00
2022-03-15 16:33:30 -07:00
if ( ceFunction - > mFailed )
* outFlags | = FrameFlags_HadError ;
2022-03-17 08:47:34 -07:00
2022-03-15 16:33:30 -07:00
int instIdx = ( int ) ( ceFrame - > mInstPtr - & ceFunction - > mCode [ 0 ] - 2 ) ;
2022-03-08 06:27:06 -08:00
2022-03-15 16:33:30 -07:00
BF_ASSERT ( ceFunction - > mId ! = - 1 ) ;
* addr = ( ( intptr ) ceFunction - > mId < < 32 ) | instIdx ;
2022-03-08 06:27:06 -08:00
2022-03-15 16:33:30 -07:00
CeEmitEntry * emitEntry = ceFunction - > FindEmitEntry ( instIdx ) ;
2022-03-08 06:27:06 -08:00
2022-03-17 08:47:34 -07:00
* outStackSize = ceContext - > mStackSize - ceFrame - > mStackAddr ;
2022-03-15 16:33:30 -07:00
if ( stackFrameIdx < mDbgCallStack . mSize - 1 )
{
auto & nextStackInfo = mDbgCallStack [ stackFrameIdx + 1 ] ;
2022-03-17 08:47:34 -07:00
if ( nextStackInfo . mFrameIdx > = 0 )
{
auto prevFrame = & ceContext - > mCallStack [ nextStackInfo . mFrameIdx ] ;
* outStackSize = prevFrame - > mStackAddr - ceFrame - > mStackAddr ;
}
2022-03-15 16:33:30 -07:00
}
2022-03-17 08:47:34 -07:00
2022-03-15 16:33:30 -07:00
CeDbgScope * ceScope = NULL ;
if ( dbgCallstackInfo . mScopeIdx ! = - 1 )
ceScope = & ceFunction - > mDbgScopes [ dbgCallstackInfo . mScopeIdx ] ;
if ( emitEntry ! = NULL )
{
if ( emitEntry - > mScope ! = - 1 )
* outFile = ceFunction - > mDbgScopes [ emitEntry - > mScope ] . mFilePath ;
* outLine = emitEntry - > mLine ;
* outColumn = emitEntry - > mColumn ;
}
if ( dbgCallstackInfo . mInlinedFrom ! = - 1 )
{
auto dbgInlineInfo = & ceFunction - > mDbgInlineTable [ dbgCallstackInfo . mInlinedFrom ] ;
* outLine = dbgInlineInfo - > mLine ;
* outColumn = dbgInlineInfo - > mColumn ;
}
if ( ( ceScope ! = NULL ) & & ( ceScope - > mMethodVal ! = - 1 ) )
{
if ( ( ceScope - > mMethodVal & CeDbgScope : : MethodValFlag_MethodRef ) ! = 0 )
2022-03-08 06:27:06 -08:00
{
2022-03-15 16:33:30 -07:00
auto dbgMethodRef = & ceFunction - > mDbgMethodRefTable [ ceScope - > mMethodVal & CeDbgScope : : MethodValFlag_IdxMask ] ;
return dbgMethodRef - > ToString ( ) ;
2022-03-08 06:27:06 -08:00
}
else
{
2022-03-15 16:33:30 -07:00
auto callTableEntry = & ceFunction - > mCallTable [ ceScope - > mMethodVal ] ;
return ceContext - > mCurModule - > MethodToString ( callTableEntry - > mFunctionInfo - > mMethodInstance ) ;
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
}
2022-03-08 06:27:06 -08:00
2022-03-15 16:33:30 -07:00
return ceContext - > mCurModule - > MethodToString ( ceFrame - > mFunction - > mMethodInstance ) ;
2022-03-08 06:27:06 -08:00
}
BfType * CeDebugger : : FindType ( const StringImpl & name )
2022-03-15 16:33:30 -07:00
{
if ( name = = " System.Object " )
return mCeMachine - > mCeModule - > mContext - > mBfObjectType ;
BfParser parser ( mCompiler - > mSystem ) ;
BfPassInstance passInstance ( mCompiler - > mSystem ) ;
parser . SetSource ( name . c_str ( ) , ( int ) name . length ( ) ) ;
parser . Parse ( & passInstance ) ;
BfReducer reducer ;
reducer . mAlloc = parser . mAlloc ;
reducer . mSystem = mCompiler - > mSystem ;
reducer . mPassInstance = & passInstance ;
reducer . mVisitorPos = BfReducer : : BfVisitorPos ( parser . mRootNode ) ;
reducer . mVisitorPos . MoveNext ( ) ;
reducer . mSource = & parser ;
auto typeRef = reducer . CreateTypeRef ( parser . mRootNode - > GetFirst ( ) ) ;
parser . Close ( ) ;
auto ceModule = mCeMachine - > mCeModule ;
SetAndRestoreValue < bool > prevIgnoreErrors ( ceModule - > mIgnoreErrors , true ) ;
SetAndRestoreValue < bool > prevIgnoreWarning ( ceModule - > mIgnoreWarnings , true ) ;
return ceModule - > ResolveTypeRef ( typeRef , { } , BfPopulateType_Declaration , BfResolveTypeRefFlag_IgnoreLookupError ) ;
2022-03-08 06:27:06 -08:00
}
String CeDebugger : : Callstack_GetStackFrameOldFileInfo ( int stackFrameIdx )
{
return String ( ) ;
}
# define CE_GET(T) *((T*)(ptr += sizeof(T)) - 1)
int CeDebugger : : GetJmpState ( int stackFrameIdx )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
if ( ! mCeMachine - > mDbgPaused )
return - 1 ;
2022-03-08 06:27:06 -08:00
if ( stackFrameIdx ! = 0 )
return - 1 ;
auto ceFrame = GetFrame ( stackFrameIdx ) ;
if ( ceFrame = = NULL )
return - 1 ;
int instIdx = ceFrame - > GetInstIdx ( ) ;
auto ptr = & ceFrame - > mFunction - > mCode [ instIdx ] ;
auto op = CE_GET ( CeOp ) ;
switch ( op )
{
case CeOp_Jmp :
return 1 ;
case CeOp_JmpIf :
case CeOp_JmpIfNot :
{
CE_GET ( int32 ) ;
int frameOfs = CE_GET ( int32 ) ;
bool willJump = * ( bool * ) ( mCeMachine - > mCurContext - > mMemory . mVals + ceFrame - > mFrameAddr + frameOfs ) ;
if ( op = = CeOp_JmpIfNot )
willJump = ! willJump ;
return willJump ? 1 : 0 ;
}
}
return - 1 ;
}
intptr CeDebugger : : GetStackFrameCalleeAddr ( int stackFrameIdx )
{
return intptr ( ) ;
}
String CeDebugger : : GetStackMethodOwner ( int stackFrameIdx , int & language )
{
return String ( ) ;
}
String CeDebugger : : FindCodeAddresses ( const StringImpl & fileName , int line , int column , bool allowAutoResolve )
{
return String ( ) ;
}
String CeDebugger : : GetAddressSourceLocation ( intptr address )
{
return String ( ) ;
}
String CeDebugger : : GetAddressSymbolName ( intptr address , bool demangle )
{
return String ( ) ;
}
String CeDebugger : : DisassembleAtRaw ( intptr address )
{
return String ( ) ;
}
String CeDebugger : : DisassembleAt ( intptr address )
{
2022-03-15 16:33:30 -07:00
AutoCrit autoCrit ( mDebugManager - > mCritSect ) ;
if ( ! mCeMachine - > mDbgPaused )
return " " ;
2022-03-08 06:27:06 -08:00
auto ceContext = mCeMachine - > mCurContext ;
mCurDisasmFuncId = ( int ) ( address > > 32 ) ;
UpdateBreakpointAddrs ( ) ;
CeFunction * ceFunction = NULL ;
if ( ! mCeMachine - > mFunctionIdMap . TryGetValue ( mCurDisasmFuncId , & ceFunction ) )
return " " ;
CeDumpContext dumpCtx ;
dumpCtx . mCeFunction = ceFunction ;
dumpCtx . mStart = & ceFunction - > mCode [ 0 ] ;
dumpCtx . mPtr = dumpCtx . mStart ;
dumpCtx . mEnd = dumpCtx . mPtr + ceFunction - > mCode . mSize ;
uint8 * start = dumpCtx . mStart ;
dumpCtx . mStr + = StrFormat ( " T Frame Size: %d \n " , ceFunction - > mFrameSize ) ;
dumpCtx . mStr + = StrFormat ( " A %llX \n " , ( intptr ) mCurDisasmFuncId < < 32 ) ;
int curEmitIdx = 0 ;
CeEmitEntry * prevEmitEntry = NULL ;
CeEmitEntry * curEmitEntry = NULL ;
2022-03-15 16:33:30 -07:00
String prevSourcePath ;
2022-03-08 06:27:06 -08:00
while ( dumpCtx . mPtr < dumpCtx . mEnd )
{
int ofs = ( int ) ( dumpCtx . mPtr - start ) ;
while ( ( curEmitIdx < ceFunction - > mEmitTable . mSize - 1 ) & & ( ofs > = ceFunction - > mEmitTable [ curEmitIdx + 1 ] . mCodePos ) )
curEmitIdx + + ;
if ( curEmitIdx < ceFunction - > mEmitTable . mSize )
curEmitEntry = & ceFunction - > mEmitTable [ curEmitIdx ] ;
if ( prevEmitEntry ! = curEmitEntry )
{
if ( ( curEmitEntry ! = NULL ) & & ( curEmitEntry - > mLine ! = - 1 ) )
{
2022-03-15 16:33:30 -07:00
bool pathChanged = false ;
2022-03-08 06:27:06 -08:00
if ( ( prevEmitEntry = = NULL ) | | ( curEmitEntry - > mScope ! = prevEmitEntry - > mScope ) )
{
2022-03-15 16:33:30 -07:00
auto ceDbgScope = & ceFunction - > mDbgScopes [ curEmitEntry - > mScope ] ;
if ( ceDbgScope - > mFilePath ! = prevSourcePath )
{
pathChanged = true ;
dumpCtx . mStr + = StrFormat ( " S %s \n " , ceDbgScope - > mFilePath . c_str ( ) ) ;
prevSourcePath = ceDbgScope - > mFilePath ;
}
2022-03-08 06:27:06 -08:00
}
2022-03-15 16:33:30 -07:00
if ( ( prevEmitEntry ! = NULL ) & & ( ! pathChanged ) & & ( curEmitEntry - > mLine > = prevEmitEntry - > mLine ) )
2022-03-08 06:27:06 -08:00
{
dumpCtx . mStr + = StrFormat ( " L %d %d \n " , prevEmitEntry - > mLine + 1 , curEmitEntry - > mLine - prevEmitEntry - > mLine ) ;
}
else
{
int startLine = BF_MAX ( 0 , curEmitEntry - > mLine - 5 ) ;
dumpCtx . mStr + = StrFormat ( " L %d %d \n " , startLine , curEmitEntry - > mLine - startLine + 1 ) ;
}
prevEmitEntry = curEmitEntry ;
}
}
dumpCtx . mStr + = StrFormat ( " D %04X: " , ofs ) ;
dumpCtx . Next ( ) ;
dumpCtx . mStr + = " \n " ;
if ( dumpCtx . mJmp ! = - 1 )
{
dumpCtx . mStr + = StrFormat ( " J %X \n " , dumpCtx . mJmp ) ;
dumpCtx . mJmp = - 1 ;
}
}
return dumpCtx . mStr ;
}
String CeDebugger : : FindLineCallAddresses ( intptr address )
{
return String ( ) ;
}
String CeDebugger : : GetCurrentException ( )
{
return String ( ) ;
}
String CeDebugger : : GetModulesInfo ( )
{
return String ( ) ;
}
void CeDebugger : : SetAliasPath ( const StringImpl & origPath , const StringImpl & localPath )
{
}
void CeDebugger : : CancelSymSrv ( )
{
}
bool CeDebugger : : HasPendingDebugLoads ( )
{
return false ;
}
int CeDebugger : : LoadImageForModule ( const StringImpl & moduleName , const StringImpl & debugFileName )
{
return 0 ;
}
int CeDebugger : : LoadDebugInfoForModule ( const StringImpl & moduleName )
{
return 0 ;
}
int CeDebugger : : LoadDebugInfoForModule ( const StringImpl & moduleName , const StringImpl & debugFileName )
{
return 0 ;
}
void CeDebugger : : StopDebugging ( )
{
mRunState = RunState_Terminating ;
mCeMachine - > mDebugEvent . Set ( true ) ;
}
void CeDebugger : : Terminate ( )
{
}
void CeDebugger : : Detach ( )
{
mRunState = RunState_Terminated ;
2022-03-15 16:33:30 -07:00
mDbgCallStack . Clear ( ) ;
2022-03-08 06:27:06 -08:00
}
Profiler * CeDebugger : : StartProfiling ( )
{
return nullptr ;
}
Profiler * CeDebugger : : PopProfiler ( )
{
return nullptr ;
}
void CeDebugger : : ReportMemory ( MemReporter * memReporter )
{
}
bool CeDebugger : : IsOnDemandDebugger ( )
{
return true ;
}
2022-04-16 06:27:54 -07:00
bool CeDebugger : : GetEmitSource ( const StringImpl & filePath , String & outText )
{
return false ;
}