source: dev/branches/egtra/ab5.0/abdev/BasicCompiler_Common/WatchList.cpp

Last change on this file was 750, checked in by イグトランス (egtra), 16 years ago

BOOST_FOREACHを可能なものはVC++ 2005 for eachへ置換(やや速くなる)。

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 Member *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 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.