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

Last change on this file since 561 was 561, checked in by dai_9181, 16 years ago

AddMemberAddDynamicMethod
・CMember→Member
・CreateMemberメソッドをCClassクラスからLexicalAnalyzerクラスへ移動した。

File size: 12.6 KB
RevLine 
[206]1#include "stdafx.h"
2
3#include <Compiler.h>
4
[76]5#include "common.h"
6
7#ifdef _AMD64_
[485]8#include "../compiler_x64/opcode.h"
[76]9#else
[484]10#include "../compiler_x86/opcode.h"
[76]11#endif
12
13//デバッグ用
14#include "debug.h"
15
[508]16using namespace ActiveBasic::Compiler;
17
[206]18int Debugging_GetArray( const Subscripts &subscripts,char *array,const Type &type,LONG_PTR *plpOffset);
[76]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){
[140]112 int i2;
[76]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]; //入れ子メンバ
[206]123 ReferenceKind refType;
[76]124 lstrcpy(VarName,member);
125 if(!GetVarFormatString(VarName,array,lpPtrOffset,NestMember, refType ) ) return 0;
126
127
128 ////////////////////////////
129 // メンバオフセットを取得
130 ////////////////////////////
131
[561]132 const Member *pMember = objClass.FindDynamicMember( VarName );
[409]133 if( !pMember )
134 {
135 return 0;
136 }
[76]137
[409]138 int offset = objClass.GetMemberOffset( VarName );
[76]139
[140]140
[76]141 //アクセシビリティをチェック
[140]142 if(( bPrivateAccess==0 && pMember->IsPrivate() )||
143 pMember->IsNoneAccess() ){
[76]144 return 0;
145 }
[140]146 else if(bPrivateAccess==0&&pMember->IsProtected())
[76]147 return 0;
148
[140]149 resultType = pMember->GetType();
[76]150
151 //ポインタ変数の場合
152 if( resultType.IsPointer() ){
[206]153 if( pMember->GetSubscripts().size() == 0 ){
[76]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(
[206]167 pMember->GetSubscripts(),
[76]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 }
[206]180 else if( pMember->GetSubscripts().size() > 0 ){
[76]181 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
182 }
183
184 if(NestMember[0]){
185 //入れ子構造の場合
186
187 if( resultType.IsObject() || resultType.IsStruct() ){
[206]188 if( refType != RefDot ) return 0;
[76]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]){
[206]203 if( refType != RefDot ) return 0;
[76]204
205 //直接参照に切り替え
206 Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
207
208 lpPtrOffset[0]=0;
209 }
210 else{
[206]211 if( refType != RefPointer ) return 0;
[76]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
[140]222 i2=Debugging_GetMember(pMember->GetType().GetClass(),
[76]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}
[206]243int Debugging_GetArray( const Subscripts &subscripts,char *array,const Type &type,LONG_PTR *plpOffset){
[76]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'){
[206]262 if( i3 >= (int)subscripts.size() )
263 {
[76]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'){
[206]276 if( i3 < (int)subscripts.size() )
277 {
[76]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
[206]312 for(i2=i+1,i4=1;i2<i3;i2++) i4*=subscripts[i2]+1;
[76]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){
[206]326 UserProc *pUserProc = GetSubFromObp(obp_Rip);
[76]327
[206]328 BOOST_FOREACH( Variable *pVar, pUserProc->GetLocalVars() ){
[76]329 if( pVar->GetName() == "_System_LocalThis" ){
[206]330 return pVar->GetOffsetAddress();
[76]331 }
332 }
333 return 0;
334}
[206]335int Debugging_GetVarOffset( char *variable,RELATIVE_VAR *pRelativeVar, Type &resultType, Subscripts *pResultSubscripts){
[76]336 extern HANDLE hDebugProcess;
[140]337 int i2,i3;
[76]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);
[206]343 ReferenceKind refType;
[76]344 GetVarFormatString(VarName,array,lpPtrOffset,member,refType);
345
[206]346 const Subscripts *pSubscripts;
[76]347 bool isArray;
348
349
350 /////////////////
351 // ローカル変数
352 /////////////////
[537]353 if( compiler.IsLocalAreaCompiling() ){
354 const Variable *pVar = compiler.GetCompilingUserProc().GetLocalVars().Find( LexicalAnalyzer::FullNameToSymbol( VarName ) );
[78]355
356 if( pVar ){
357 //ポインタ変数の場合
[206]358 if( pVar->GetType().IsPointer() ){
[78]359 if( !pVar->IsArray() ){
360 lstrcpy(lpPtrOffset,array);
361 array[0]=0;
362 }
[76]363 }
[78]364 else{
365 if(lpPtrOffset[0]) return 0;
366 }
367
[206]368 pRelativeVar->offset = pVar->GetOffsetAddress();
[78]369 if( pVar->IsRef() ){
370 pRelativeVar->dwKind=VAR_REFLOCAL;
371 }
372 else{
373 pRelativeVar->dwKind=VAR_LOCAL;
374 }
[206]375 resultType = pVar->GetType();
[78]376 isArray = pVar->IsArray();
[206]377 pSubscripts = &pVar->GetSubscripts();
[76]378 }
[78]379 }
[76]380
[536]381 if( compiler.IsCompilingClass() )
382 {
[78]383 ///////////////////////
384 // クラスメンバの参照
385 ///////////////////////
386
387 if(memicmp(variable,"This.",5)==0){
388 //Thisオブジェクトのメンバを参照するとき
389 SlideString(variable+5,-5);
390 lstrcpy(VarName,variable);
[76]391 }
392 else{
[409]393 //クラス内の動的メンバを参照するとき(通常)
[76]394
[536]395 if( !compiler.GetCompilingClass().HasDynamicMember( VarName ) )
[409]396 {
397 goto NonClassMember;
[76]398 }
[78]399 }
[76]400
[78]401 /////////////////////////////
402 // thisポインタを取得
[76]403
[78]404 extern HWND hDebugWnd;
405 i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
406 i2=pobj_dti->iProcLevel-i2;
[76]407
[78]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 }
[76]418
[78]419 pRelativeVar->dwKind=VAR_DIRECTMEM;
[76]420
[536]421 i3=Debugging_GetMember( compiler.GetCompilingClass(),variable,pRelativeVar,resultType,1);
[78]422 if(i3==0){
423 //式エラー
424 return 0;
425 }
426 if(i3==-1){
427 //アクセスエラー
428 return -1;
429 }
[76]430
[78]431 return 1;
432 }
[76]433
434NonClassMember:
435
[78]436 {
[76]437 ///////////////////
438 // グローバル変数
439 ///////////////////
440
[508]441 const Variable *pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( VarName ) );
[76]442 if( !pVar ){
443 //一致しないとき
444 return 0;
445 }
446
447 //ポインタ変数の場合
[206]448 if( pVar->GetType().IsPointer() ){
[76]449 if( !pVar->IsArray() ){
450 lstrcpy(lpPtrOffset,array);
451 array[0]=0;
452 }
453 }
454 else{
455 if(lpPtrOffset[0]) return 0;
456 }
457
[206]458 pRelativeVar->offset=pVar->GetOffsetAddress();
[76]459 if(pVar->IsRef()) pRelativeVar->dwKind=VAR_REFGLOBAL;
460 else pRelativeVar->dwKind=VAR_GLOBAL;
[206]461 resultType = pVar->GetType();
[76]462 isArray = pVar->IsArray();
[206]463 pSubscripts = &pVar->GetSubscripts();
[76]464 }
465
466
467 if(array[0]==0&&isArray){
468 //配列の先頭ポインタを示す場合
469 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
[206]470 if( pResultSubscripts )
471 {
472 (*pResultSubscripts) = *pSubscripts;
473 }
[76]474 return 1;
475 }
476
477 if(array[0]){
[206]478 i3=Debugging_GetArray( *pSubscripts, array,resultType,&pRelativeVar->offset);
[76]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)
[206]491 if( refType != RefDot ){
[76]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
[206]509 if( refType != RefDot ) return 0;
[76]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
[206]524 if( refType != RefPointer ) return 0;
[76]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.