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

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

Symbolコンストラクタを少なくし、LexicalAnalyzer::FullNameToSymbolメソッドを実装。

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( UserProc::IsLocalAreaCompiling() ){
354 const Variable *pVar = UserProc::CompilingUserProc().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.pCompilingClass){
382 ///////////////////////
383 // クラスメンバの参照
384 ///////////////////////
385
386 if(memicmp(variable,"This.",5)==0){
387 //Thisオブジェクトのメンバを参照するとき
388 SlideString(variable+5,-5);
389 lstrcpy(VarName,variable);
390 }
391 else{
392 //クラス内の動的メンバを参照するとき(通常)
393
394 if( !compiler.pCompilingClass->HasDynamicMember( VarName ) )
395 {
396 goto NonClassMember;
397 }
398 }
399
400 /////////////////////////////
401 // thisポインタを取得
402
403 extern HWND hDebugWnd;
404 i2=(int)SendDlgItemMessage(hDebugWnd,IDC_PROCCOMBO,CB_GETCURSEL,0,0);
405 i2=pobj_dti->iProcLevel-i2;
406
407 lpData=Debugging_GetThisPtrOffset(pobj_dti->lplpObp[i2]);
408 if(!lpData){
409 //式エラー
410 return 0;
411 }
412 lpData+=pobj_dti->lplpSpBase[i2];
413 if(!ReadProcessMemory(hDebugProcess,(void *)lpData,&pRelativeVar->offset,sizeof(LONG_PTR),&accessBytes)){
414 //メモリにアクセスできないとき
415 return -1;
416 }
417
418 pRelativeVar->dwKind=VAR_DIRECTMEM;
419
420 i3=Debugging_GetMember(*compiler.pCompilingClass,variable,pRelativeVar,resultType,1);
421 if(i3==0){
422 //式エラー
423 return 0;
424 }
425 if(i3==-1){
426 //アクセスエラー
427 return -1;
428 }
429
430 return 1;
431 }
432
433NonClassMember:
434
435 {
436 ///////////////////
437 // グローバル変数
438 ///////////////////
439
440 const Variable *pVar = compiler.GetObjectModule().meta.GetGlobalVars().Find( LexicalAnalyzer::FullNameToSymbol( VarName ) );
441 if( !pVar ){
442 //一致しないとき
443 return 0;
444 }
445
446 //ポインタ変数の場合
447 if( pVar->GetType().IsPointer() ){
448 if( !pVar->IsArray() ){
449 lstrcpy(lpPtrOffset,array);
450 array[0]=0;
451 }
452 }
453 else{
454 if(lpPtrOffset[0]) return 0;
455 }
456
457 pRelativeVar->offset=pVar->GetOffsetAddress();
458 if(pVar->IsRef()) pRelativeVar->dwKind=VAR_REFGLOBAL;
459 else pRelativeVar->dwKind=VAR_GLOBAL;
460 resultType = pVar->GetType();
461 isArray = pVar->IsArray();
462 pSubscripts = &pVar->GetSubscripts();
463 }
464
465
466 if(array[0]==0&&isArray){
467 //配列の先頭ポインタを示す場合
468 resultType.SetBasicType( resultType.GetBasicType() | FLAG_PTR );
469 if( pResultSubscripts )
470 {
471 (*pResultSubscripts) = *pSubscripts;
472 }
473 return 1;
474 }
475
476 if(array[0]){
477 i3=Debugging_GetArray( *pSubscripts, array,resultType,&pRelativeVar->offset);
478 if(i3==0){
479 //式エラー
480 return 0;
481 }
482 if(i3==-1){
483 //アクセスエラー
484 return -1;
485 }
486 }
487 if(member[0]){
488 if( resultType.IsObject() || resultType.IsStruct() ){
489 //実態オブジェクトのメンバを参照(obj.member)
490 if( refType != RefDot ){
491 return 0;
492 }
493
494 i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
495 if(i3==0){
496 //式エラー
497 return 0;
498 }
499 if(i3==-1){
500 //アクセスエラー
501 return -1;
502 }
503 }
504 else if( resultType.IsObjectPtr() || resultType.IsStructPtr() ){
505 //ポインタオブジェクトが示すメンバを参照
506 if(lpPtrOffset[0]){
507 //pObj[n].member
508 if( refType != RefDot ) return 0;
509 Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset);
510
511 i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
512 if(i3==0){
513 //式エラー
514 return 0;
515 }
516 if(i3==-1){
517 //アクセスエラー
518 return -1;
519 }
520 }
521 else{
522 //pObj->member
523 if( refType != RefPointer ) return 0;
524
525 pRelativeVar->offset=Debugging_GetVarPtr(pRelativeVar);
526 pRelativeVar->dwKind=VAR_DIRECTMEM;
527
528 if(!ReadProcessMemory(hDebugProcess,(void *)pRelativeVar->offset,&lpData,sizeof(LONG_PTR),&accessBytes)) return -1;
529 pRelativeVar->offset=lpData;
530
531 i3=Debugging_GetMember(resultType.GetClass(),member,pRelativeVar,resultType,0);
532 if(i3==0){
533 //式エラー
534 return 0;
535 }
536 if(i3==-1){
537 //アクセスエラー
538 return -1;
539 }
540 }
541 }
542 else{
543 return 0;
544 }
545 return 1;
546 }
547
548 if(lpPtrOffset[0]){
549 if(!Debugging_SetRelativeOffset(resultType,pRelativeVar,lpPtrOffset)) return 0;
550 }
551
552 return 1;
553}
Note: See TracBrowser for help on using the repository browser.