source: dev/trunk/ab5.0/abdev/BasicCompiler_Common/WatchList.cpp @ 537

Last change on this file since 537 was 537, checked in by dai_9181, 15 years ago

UserProcクラスによるコンパイル中関数管理用メソッドを除去(すべてCompilerクラス内で処理するようにした)。

File size: 12.6 KB
Line 
1#include "stdafx.h"
2
3#include <Compiler.h>
4
5#include "common.h"
6
7#ifdef _AMD64_
8#include "../compiler_x64/opcode.h"
9#else
10#include "../compiler_x86/opcode.h"
11#endif
12
13//デバッグ用
14#include "debug.h"
15
16using namespace ActiveBasic::Compiler;
17
18int Debugging_GetArray( const Subscripts &subscripts,char *array,const Type &type,LONG_PTR *plpOffset);
19
20ULONG_PTR Debugging_GetVarPtr(RELATIVE_VAR *pRelativeVar){
21    extern DWORD ImageBase;
22    extern int MemPos_RWSection;
23    int i2;
24
25    if(pRelativeVar->dwKind==VAR_GLOBAL){
26        return ImageBase+MemPos_RWSection+pRelativeVar->offset;
27    }
28    else if( pRelativeVar->dwKind == VAR_REFGLOBAL ){
29        extern HANDLE hDebugProcess;
30        LONG_PTR lpData;
31        SIZE_T accessBytes;
32        ReadProcessMemory(hDebugProcess,
33            (void *)(ImageBase+MemPos_RWSection+pRelativeVar->offset),
34            &lpData,
35            sizeof(LONG_PTR),
36            &accessBytes);
37
38        return lpData;
39    }
40    else if(pRelativeVar->dwKind==VAR_LOCAL){
41        extern HWND hDebugWnd;
42        i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
43        i2=pobj_dti->iProcLevel-i2;
44
45        if(pobj_dti->lplpSpBase[i2]==0) return 0;
46
47        return pobj_dti->lplpSpBase[i2]+pRelativeVar->offset;
48    }
49    else if( pRelativeVar->dwKind == VAR_REFLOCAL ){
50        extern HWND hDebugWnd;
51        i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
52        i2=pobj_dti->iProcLevel-i2;
53
54        if(pobj_dti->lplpSpBase[i2]==0) return 0;
55
56        extern HANDLE hDebugProcess;
57        LONG_PTR lpData;
58        SIZE_T accessBytes;
59        ReadProcessMemory(hDebugProcess,
60            (void *)(pobj_dti->lplpSpBase[i2]+(int)pRelativeVar->offset),
61            &lpData,
62            sizeof(LONG_PTR),
63            &accessBytes);
64
65        return lpData;
66    }
67    else if(pRelativeVar->dwKind==VAR_DIRECTMEM){
68        return pRelativeVar->offset;
69    }
70
71    return 0;
72}
73
74bool Debugging_SetRelativeOffset( Type &type,RELATIVE_VAR *pRelativeVar,char *lpPtrOffset){
75    int array_num;
76
77    _int64 i64data;
78    if( !StaticCalculation( true, lpPtrOffset, 0, &i64data, Type(), 1 ) ){
79        return false;
80    }
81    if( type.IsReal() ){
82        double dbl;
83        memcpy(&dbl,&i64data,sizeof(double));
84        i64data=(_int64)dbl;
85    }
86
87    array_num=(int)i64data;
88
89    if( type.PtrLevel() ){
90        type.PtrLevelDown();
91        array_num *= type.GetSize();
92    }
93    else{
94        //エラー
95        return false;
96    }
97
98    extern HANDLE hDebugProcess;
99    LONG_PTR lpData;
100    SIZE_T accessBytes;
101    lpData=Debugging_GetVarPtr(pRelativeVar);
102    if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)){
103        return false;
104    }
105    pRelativeVar->dwKind=VAR_DIRECTMEM;
106
107    pRelativeVar->offset+=array_num;
108    return true;
109}
110
111int Debugging_GetMember( const CClass &objClass,char *member,RELATIVE_VAR *pRelativeVar, Type &resultType, BOOL bPrivateAccess){
112    int i2;
113
114    //直接参照に切り替え
115    pRelativeVar->offset=(LONG_PTR)Debugging_GetVarPtr(pRelativeVar);
116    pRelativeVar->dwKind=VAR_DIRECTMEM;
117
118    //クラス、配列の構成要素を解析する
119    char VarName[VN_SIZE];      //変数名
120    char array[VN_SIZE];        //第1次配列
121    char lpPtrOffset[VN_SIZE];  //第2次配列
122    char NestMember[VN_SIZE];   //入れ子メンバ
123    ReferenceKind refType;
124    lstrcpy(VarName,member);
125    if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember, refType ) ) return 0;
126
127
128    ////////////////////////////
129    // メンバオフセットを取得
130    ////////////////////////////
131
132    const CMember *pMember = objClass.FindDynamicMember( VarName );
133    if( !pMember )
134    {
135        return 0;
136    }
137
138    int offset = objClass.GetMemberOffset( VarName );
139
140
141    //アクセシビリティをチェック
142    if(( bPrivateAccess==0 && pMember->IsPrivate() )||
143        pMember->IsNoneAccess() ){
144        return 0;
145    }
146    else if(bPrivateAccess==0&&pMember->IsProtected())
147        return 0;
148
149    resultType = pMember->GetType();
150
151    //ポインタ変数の場合
152    if( resultType.IsPointer() ){
153        if( pMember->GetSubscripts().size() == 0 ){
154            lstrcpy(lpPtrOffset,array);
155            array[0]=0;
156        }
157    }
158    else{
159        if(lpPtrOffset[0]) return 0;
160    }
161
162    pRelativeVar->offset+=offset;
163
164    if(array[0]){
165        //配列オフセット
166        i2=Debugging_GetArray(
167            pMember->GetSubscripts(),
168            array,
169            resultType,
170            &pRelativeVar->offset);
171        if(i2==0){
172            //式エラー
173            return 0;
174        }
175        if(i2==-1){
176            //アクセスエラー
177            return -1;
178        }
179    }
180    else if( pMember->GetSubscripts().size() > 0 ){
181        resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
182    }
183
184    if(NestMember[0]){
185        //入れ子構造の場合
186
187        if( resultType.IsObject() || resultType.IsStruct() ){
188            if( refType != RefDot ) return 0;
189
190            if( resultType.IsObject() ){
191                extern HANDLE hDebugProcess;
192                LONG_PTR lpData;
193                SIZE_T accessBytes;
194                lpData=Debugging_GetVarPtr(pRelativeVar);
195                if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)) return -1;
196                pRelativeVar->dwKind=VAR_DIRECTMEM;
197            }
198        }
199        else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
200            //構造体ポインタ型メンバ変数
201
202            if(lpPtrOffset[0]){
203                if( refType != RefDot ) return 0;
204
205                //直接参照に切り替え
206                Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
207
208                lpPtrOffset[0]=0;
209            }
210            else{
211                if( refType != RefPointer ) return 0;
212
213                extern HANDLE hDebugProcess;
214                LONG_PTR lpData;
215                SIZE_T accessBytes;
216                lpData=Debugging_GetVarPtr(pRelativeVar);
217                if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)) return -1;
218                pRelativeVar->dwKind=VAR_DIRECTMEM;
219            }
220        }
221
222        i2=Debugging_GetMember(pMember->GetType().GetClass(),
223            NestMember,
224            pRelativeVar,
225            resultType,
226            0);
227        if(i2==0){
228            //式エラー
229            return 0;
230        }
231        if(i2==-1){
232            //アクセスエラー
233            return -1;
234        }
235    }
236
237    if(lpPtrOffset[0]){
238        Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
239    }
240
241    return 1;
242}
243int Debugging_GetArray( const Subscripts &subscripts,char *array,const Type &type,LONG_PTR *plpOffset){
244    extern HANDLE hHeap;
245    int i,i2,i3,i4,i5,array_offset;
246    char temporary[VN_SIZE],*pParm[MAX_PARMS];
247
248    for(i=0,i2=0,i3=0;;i++,i2++){
249        if(array[i]=='('){
250            i4=GetStringInPare(temporary+i2,array+i);
251            i+=i4-1;
252            i2+=i4-1;
253            continue;
254        }
255        if(array[i]=='['){
256            i4=GetStringInBracket(temporary+i2,array+i);
257            i+=i4-1;
258            i2+=i4-1;
259            continue;
260        }
261        if(array[i]==','||array[i]=='\0'){
262            if( i3 >= (int)subscripts.size() )
263            {
264                for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
265                return 0;
266            }
267
268            temporary[i2]=0;
269
270            pParm[i3]=(char *)HeapAlloc(hHeap,0,lstrlen(temporary)+1);
271            lstrcpy(pParm[i3],temporary);
272
273            i3++;
274
275            if(array[i]=='\0'){
276                if( i3 < (int)subscripts.size() )
277                {
278                    for(i3--;i3>=0;i3--) HeapDefaultFree(pParm[i3]);
279                    return 0;
280                }
281                break;
282            }
283
284            i2=-1;
285            continue;
286        }
287        temporary[i2]=array[i];
288    }
289
290    array_offset=0;
291
292    for(i=i3-1;i>=0;i--){
293        _int64 i64data;
294        Type resultType;
295        bool isMemoryAccessError;
296        if( !StaticCalculation(true, pParm[i],0,&i64data,resultType,1, &isMemoryAccessError ) ){
297            //式エラー
298            return 0;
299        }
300        if(isMemoryAccessError){
301            //アクセスエラー
302            return -1;
303        }
304
305        if(resultType.IsReal()){
306            double dbl;
307            memcpy(&dbl,&i64data,sizeof(double));
308            i64data=(_int64)dbl;
309        }
310        i5=(int)i64data;
311
312        for(i2=i+1,i4=1;i2<i3;i2++) i4*=subscripts[i2]+1;
313
314        array_offset+=i5*i4;
315
316        HeapDefaultFree(pParm[i]);
317    }
318
319    array_offset *= type.GetSize();
320
321    *plpOffset+=array_offset;
322
323    return 1;
324}
325ULONG_PTR Debugging_GetThisPtrOffset(LONG_PTR obp_Rip){
326    UserProc *pUserProc = GetSubFromObp(obp_Rip);
327
328    BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){
329        if( pVar->GetName() == "_System_LocalThis" ){
330            return pVar->GetOffsetAddress();
331        }
332    }
333    return 0;
334}
335int Debugging_GetVarOffset( char *variable,RELATIVE_VAR *pRelativeVar, Type &resultType, Subscripts *pResultSubscripts){
336    extern HANDLE hDebugProcess;
337    int i2,i3;
338    char member[VN_SIZE],VarName[VN_SIZE],array[VN_SIZE],lpPtrOffset[VN_SIZE];
339    LONG_PTR lpData;
340    SIZE_T accessBytes;
341
342    lstrcpy(VarName,variable);
343    ReferenceKind refType;
344    GetVarFormatString(VarName,array,lpPtrOffset,member,refType);
345
346    const Subscripts *pSubscripts;
347    bool isArray;
348
349
350    /////////////////
351    // ローカル変数
352    /////////////////
353    if( compiler.IsLocalAreaCompiling() ){
354        const Variable *pVar = compiler.GetCompilingUserProc().GetLocalVars().Find( LexicalAnalyzer::FullNameToSymbol( VarName ) );
355
356        if( pVar ){
357            //ポインタ変数の場合
358            if( pVar->GetType().IsPointer() ){
359                if( !pVar->IsArray() ){
360                    lstrcpy(lpPtrOffset,array);
361                    array[0]=0;
362                }
363            }
364            else{
365                if(lpPtrOffset[0]) return 0;
366            }
367
368            pRelativeVar->offset = pVar->GetOffsetAddress();
369            if( pVar->IsRef() ){
370                pRelativeVar->dwKind=VAR_REFLOCAL;
371            }
372            else{
373                pRelativeVar->dwKind=VAR_LOCAL;
374            }
375            resultType = pVar->GetType();
376            isArray = pVar->IsArray();
377            pSubscripts = &pVar->GetSubscripts();
378        }
379    }
380
381    if( compiler.IsCompilingClass() )
382    {
383        ///////////////////////
384        // クラスメンバの参照
385        ///////////////////////
386
387        if(memicmp(variable,"This.",5)==0){
388            //Thisオブジェクトのメンバを参照するとき
389            SlideString(variable+5,-5);
390            lstrcpy(VarName,variable);
391        }
392        else{
393            //クラス内の動的メンバを参照するとき(通常)
394
395            if( !compiler.GetCompilingClass().HasDynamicMember( VarName ) )
396            {
397                goto NonClassMember;
398            }
399        }
400
401        /////////////////////////////
402        // thisポインタを取得
403
404        extern HWND hDebugWnd;
405        i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
406        i2=pobj_dti->iProcLevel-i2;
407
408        lpData=Debugging_GetThisPtrOffset(pobj_dti->lplpObp[i2]);
409        if(!lpData){
410            //式エラー
411            return 0;
412        }
413        lpData+=pobj_dti->lplpSpBase[i2];
414        if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)){
415            //メモリにアクセスできないとき
416            return -1;
417        }
418
419        pRelativeVar->dwKind=VAR_DIRECTMEM;
420
421        i3=Debugging_GetMember( compiler.GetCompilingClass(),variable,pRelativeVar,resultType,1);
422        if(i3==0){
423            //式エラー
424            return 0;
425        }
426        if(i3==-1){
427            //アクセスエラー
428            return -1;
429        }
430
431        return 1;
432    }
433
434NonClassMember:
435
436    {
437        ///////////////////
438        // グローバル変数
439        ///////////////////
440
441        const Variable *pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( VarName ) );
442        if( !pVar ){
443            //一致しないとき
444            return 0;
445        }
446
447        //ポインタ変数の場合
448        if( pVar->GetType().IsPointer() ){
449            if( !pVar->IsArray() ){
450                lstrcpy(lpPtrOffset,array);
451                array[0]=0;
452            }
453        }
454        else{
455            if(lpPtrOffset[0]) return 0;
456        }
457
458        pRelativeVar->offset=pVar->GetOffsetAddress();
459        if(pVar->IsRef()) pRelativeVar->dwKind=VAR_REFGLOBAL;
460        else pRelativeVar->dwKind=VAR_GLOBAL;
461        resultType = pVar->GetType();
462        isArray = pVar->IsArray();
463        pSubscripts = &pVar->GetSubscripts();
464    }
465
466
467    if(array[0]==0&&isArray){
468        //配列の先頭ポインタを示す場合
469        resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
470        if( pResultSubscripts )
471        {
472            (*pResultSubscripts) = *pSubscripts;
473        }
474        return 1;
475    }
476
477    if(array[0]){
478        i3=Debugging_GetArray( *pSubscripts, array,resultType,&pRelativeVar->offset);
479        if(i3==0){
480            //式エラー
481            return 0;
482        }
483        if(i3==-1){
484            //アクセスエラー
485            return -1;
486        }
487    }
488    if(member[0]){
489        if( resultType.IsObject() || resultType.IsStruct() ){
490            //実態オブジェクトのメンバを参照(obj.member)
491            if( refType != RefDot ){
492                return 0;
493            }
494
495            i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
496            if(i3==0){
497                //式エラー
498                return 0;
499            }
500            if(i3==-1){
501                //アクセスエラー
502                return -1;
503            }
504        }
505        else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
506            //ポインタオブジェクトが示すメンバを参照
507            if(lpPtrOffset[0]){
508                //pObj[n].member
509                if( refType != RefDot ) return 0;
510                Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
511
512                i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
513                if(i3==0){
514                    //式エラー
515                    return 0;
516                }
517                if(i3==-1){
518                    //アクセスエラー
519                    return -1;
520                }
521            }
522            else{
523                //pObj->member
524                if( refType != RefPointer ) return 0;
525
526                pRelativeVar->offset=Debugging_GetVarPtr(pRelativeVar);
527                pRelativeVar->dwKind=VAR_DIRECTMEM;
528
529                if(!ReadProcessMemory(hDebugProcess,(void *)pRelativeVar->offset,&lpData,sizeof(LONG_PTR),&accessBytes)) return -1;
530                pRelativeVar->offset=lpData;
531
532                i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
533                if(i3==0){
534                    //式エラー
535                    return 0;
536                }
537                if(i3==-1){
538                    //アクセスエラー
539                    return -1;
540                }
541            }
542        }
543        else{
544            return 0;
545        }
546        return 1;
547    }
548
549    if(lpPtrOffset[0]){
550        if(!Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset)) return 0;
551    }
552
553    return 1;
554}
Note: See TracBrowser for help on using the repository browser.