source: dev/BasicCompiler32/Compile_CallProc.cpp@ 26

Last change on this file since 26 was 26, checked in by dai_9181, 17 years ago

実体オブジェクトを戻り値に持つ静的メソッドをクラス内から呼び出すと「パラメータが異なる」というエラーが出るバグを修正。
Exceptionに関するファイルを追加。

File size: 12.8 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "Opcode.h"
3
4//ローカル変数アドレススケジュール
5DWORD *pLocalVarAddrSchedule;
6int LocalVarAddrScheduleNum;
7
8void Call_DebugSys_SaveContext(){
9 //call _System_GetEip
10 extern SUBINFO *pSub_System_GetEip;
11 op_call(pSub_System_GetEip);
12
13 //push eax
14 op_push(REG_EAX);
15
16 //push ebp
17 op_push(REG_EBP);
18
19 //call _DebugSys_SaveContext
20 extern SUBINFO *pSub_DebugSys_SaveContext;
21 op_call(pSub_DebugSys_SaveContext);
22}
23
24void AddLocalVarAddrSchedule(){
25 extern HANDLE hHeap;
26
27 //ローカル変数アドレススケジュールに追加する
28 pLocalVarAddrSchedule=(DWORD *)HeapReAlloc(hHeap,0,pLocalVarAddrSchedule,(LocalVarAddrScheduleNum+1)*sizeof(DWORD));
29 pLocalVarAddrSchedule[LocalVarAddrScheduleNum]=obp;
30 LocalVarAddrScheduleNum++;
31}
32int CallProc(int idProc,void *pInfo,char *name,char *Parameter,LONG_PTR *plpRetIndex){
33 int ret_type;
34
35 if(idProc==PROC_DEFAULT){
36 /////////////////////
37 // ユーザー定義関数
38 /////////////////////
39
40 SUBINFO *psi;
41 psi=(SUBINFO *)pInfo;
42
43 //GetSubHash内でエラー提示が行われた場合
44 if(psi==(SUBINFO *)-1) return -1;
45
46
47 //オブジェクト名を取得
48 char ObjectName[VN_SIZE];
49 int RefType;
50 GetObjectName(name,ObjectName,&RefType);
51
52
53 ////////////////////////
54 // オーバーロードを解決
55 ////////////////////////
56
57 SUBINFO **ppsi;
58 int num;
59 ppsi=GetOverloadSubHash(name,&num);
60 if(num){
61 //オーバーロードを解決
62 psi=OverloadSolutionWithStrParam(name,ppsi,num,Parameter,ObjectName,NULL);
63 HeapDefaultFree(ppsi);
64
65 if(!psi) return 0;
66 }
67
68
69 ret_type=Opcode_CallProc(Parameter,psi,plpRetIndex,0,ObjectName,RefType);
70 }
71 else if(idProc==PROC_DLL){
72 /////////////////////////
73 // DLL関数
74 /////////////////////////
75 DECLAREINFO *pdi;
76 pdi=(DECLAREINFO *)pInfo;
77
78 ret_type=Opcode_CallDllProc(Parameter,pdi,plpRetIndex);
79 }
80 else if(idProc==PROC_BUILTIN){
81 /////////////////////////
82 // 組み込み関数
83 /////////////////////////
84 int FuncId;
85 FuncId=(int)(_int64)pInfo;
86
87 ret_type=Opcode_CallFunc(Parameter,FuncId);
88 }
89 else if(idProc==PROC_PTR){
90 /////////////////
91 // 関数ポインタ
92 /////////////////
93
94 LONG_PTR lpIndex;
95 GetVarType(name,&lpIndex,0);
96
97 extern PROCPTRINFO *pProcPtrInfo;
98 ret_type=Opcode_CallProcPtr(name,Parameter,&pProcPtrInfo[lpIndex],plpRetIndex);
99 }
100
101 return ret_type;
102}
103
104BOOL CallPropertyMethod(char *variable,char *RightSide,TYPEINFO *pRetTypeInfo){
105 //プロパティ用のメソッドを呼び出す
106
107 //配列要素を取得
108 char VarName[VN_SIZE],ArrayElements[VN_SIZE];
109 GetArrayElement(variable,VarName,ArrayElements);
110
111 //オブジェクト名を取得
112 char ObjectName[VN_SIZE];
113 int RefType;
114 GetObjectName(VarName,ObjectName,&RefType);
115
116 //オーバーロード用の関数リストを作成
117 SUBINFO **ppsi;
118 int num;
119 ppsi=GetOverloadSubHash(VarName,&num);
120 if(num==0){
121 return 0;
122 }
123
124 //パラメータを整備
125 char *Parameter;
126 Parameter=(char *)HeapAlloc(hHeap,0,lstrlen(ArrayElements)+lstrlen(RightSide)+32);
127 lstrcpy(Parameter,ArrayElements);
128 if(RightSide){
129 if(Parameter[0]&&RightSide[0]) lstrcat(Parameter,",");
130 lstrcat(Parameter,RightSide);
131 }
132
133 //オーバーロードを解決
134 SUBINFO *psi;
135 psi=OverloadSolutionWithStrParam(VarName,ppsi,num,Parameter,ObjectName,NULL);
136 HeapDefaultFree(ppsi);
137
138 if(psi){
139 //呼び出し
140 int type;
141 LONG_PTR lpIndex;
142 type=Opcode_CallProc(Parameter,psi,&lpIndex,0,ObjectName,RefType);
143
144 if(pRetTypeInfo){
145 pRetTypeInfo->type=type;
146 pRetTypeInfo->u.lpIndex=lpIndex;
147 }
148 }
149
150 HeapDefaultFree(Parameter);
151
152 return 1;
153}
154
155
156int Opcode_CallProcPtr(char *variable,char *Parameter,PROCPTRINFO *pi,LONG_PTR *plpIndex){
157 extern HANDLE hHeap;
158 int i;
159
160
161 extern BOOL bDebugCompile;
162 extern BOOL bDebugSupportProc;
163 if(bDebugCompile&&bDebugSupportProc==0)
164 Call_DebugSys_SaveContext();
165
166
167 ////////////////////////
168 // パラメータのセット
169 ////////////////////////
170
171 //パラメータオブジェクトを生成
172 CParameter *pobj_parameter=0;
173 pobj_parameter=new CParameter(Parameter);
174
175 //エラーチェック
176 pobj_parameter->ErrorCheck(variable,pi->pParmInfo,pi->ParmNum,pi->ParmNum);
177
178 //一時オブジェクトを生成
179 pobj_parameter->NewTempParameters( variable,pi->pParmInfo,pi->ParmNum,pi->ParmNum );
180
181 //レジスタ、スタックフレームにセット
182 pobj_parameter->SetParameter(variable,pi->pParmInfo,pi->ParmNum,pi->ParmNum);
183
184
185
186 ////////////////////////
187 // call
188 ////////////////////////
189 RELATIVE_VAR RelativeVar;
190 LONG_PTR lp;
191 GetVarOffsetReadOnly(variable,&i,&RelativeVar,&lp);
192 SetVarPtrToEax(&RelativeVar);
193
194 //mov eax,dword ptr[eax]
195 OpBuffer[obp++]=(char)0x8B;
196 OpBuffer[obp++]=(char)0x00;
197
198 //call eax
199 OpBuffer[obp++]=(char)0xFF;
200 OpBuffer[obp++]=(char)0xD0;
201
202
203
204 //一時オブジェクトを破棄
205 pobj_parameter->DeleteTempParameters();
206
207 //パラメータオブジェクトを破棄
208 delete pobj_parameter;
209
210 if(plpIndex) *plpIndex=pi->u.ReturnIndex;
211
212 return pi->ReturnType;
213}
214
215int Opcode_CallProc(char *Parameter,SUBINFO *psi,LONG_PTR *plpIndex,DWORD dwFlags,char *ObjectName,int RefType){
216 int i,i2;
217
218 if(psi->dwType==SUBTYPE_MACRO){
219 if(lstrcmpi(psi->name,"Print")==0){
220 Opcode_Print(Parameter,0);
221 return -1;
222 }
223 if(lstrcmpi(psi->name,"Input")==0){
224 Opcode_Input(Parameter);
225 return -1;
226 }
227 if(lstrcmpi(psi->name,"Write")==0){
228 Opcode_Print(Parameter,1);
229 return -1;
230 }
231 }
232
233 psi->bUse=1;
234
235 BOOL bStatic=0;
236 CClass *pobj_c = NULL;
237 CMethod *pMethod = NULL;
238 if(psi->pobj_ParentClass){
239 //クラスのメンバ関数を呼び出す場合はアクセスチェックを行う
240 if(ObjectName[0]){
241 if(lstrcmpi(ObjectName,"Super")==0){
242 //クラスメンバ関数内からスーパークラスの呼び出し
243 pobj_c=pobj_CompilingClass;
244 }
245 else{
246 pobj_c=pobj_DBClass->check(ObjectName);
247 if(pobj_c){
248 //静的メンバ
249 bStatic=1;
250 }
251 else{
252 //"->"によってオブジェクトを指定する通常のメンバ関数呼び出し
253 GetVarType(ObjectName,(LONG_PTR *)&pobj_c,1);
254 }
255 }
256 }
257 else{
258 if(dwFlags&PROCFLAG_NEW){
259 //New演算子によるコンストラクタ呼び出し
260 pobj_c=psi->pobj_ParentClass;
261 }
262 else{
263 //クラスメンバ関数内から同一クラスのメンバ関数の呼び出し
264 pobj_c=pobj_CompilingClass;
265 }
266 }
267
268
269 /////////////////////////////////
270 // メソッド情報を取得
271 /////////////////////////////////
272 pMethod = pobj_c->GetMethodInfo( psi );
273 if( !pMethod ){
274 //動的メソッドが取得できなかったときは静的メソッドを当たる
275 pMethod = pobj_c->GetStaticMethodInfo( psi );
276 if( !pMethod ){
277 SetError(300,NULL,cp);
278 return -1;
279 }
280
281 //静的メンバ
282 bStatic=1;
283 }
284
285
286 //////////////////////////////
287 // アクセスエラーチェック
288 //////////////////////////////
289 DWORD dwAccess = pMethod->dwAccess;
290
291 if(ObjectName[0]){
292 //外部からの呼び出し
293 if(pobj_c==pobj_CompilingClass){
294 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
295 if(dwAccess==ACCESS_NON){
296 SetError(109,psi->name,cp);
297 return -1;
298 }
299 }
300 else{
301 if(dwAccess==ACCESS_PRIVATE||
302 dwAccess==ACCESS_NON){
303 SetError(109,psi->name,cp);
304 return -1;
305 }
306 if(dwAccess==ACCESS_PROTECTED){
307 SetError(110,psi->name,cp);
308 return -1;
309 }
310 }
311 }
312 else{
313 //クラス内部からの呼び出し(継承によるACCESS_NONのみをエラーとする)
314 if(dwAccess==ACCESS_NON){
315 SetError(109,psi->name,cp);
316 return -1;
317 }
318 }
319 }
320
321
322
323 ///////////////////////////////////////////////////////////////
324 // _System_LocalThis、_System_ReturnObjectのダミーをセット
325 ///////////////////////////////////////////////////////////////
326
327 char temporary[VN_SIZE]={0};
328 if(psi->pobj_ParentClass&&bStatic==0){
329 //_System_LocalThis(第一パラメータ)のダミーを作成
330 lstrcpy(temporary,"0,");
331 }
332
333 if(psi->ReturnType==DEF_OBJECT){
334 //_System_ReturnObject(第一または第二パラメータのダミーを作成)
335 sprintf(temporary+lstrlen(temporary),"%c%c0,",1,ESC_BYVAL);
336 }
337
338 if(Parameter[0]=='\0'&&temporary[0])
339 temporary[lstrlen(temporary)-1]=0;
340 else lstrcat(temporary,Parameter);
341
342
343
344 ////////////////////////
345 // パラメータをセット
346 ////////////////////////
347
348 //パラメータオブジェクトを生成
349 CParameter *pobj_parameter=0;
350 pobj_parameter=new CParameter(temporary);
351
352 //エラーチェック
353 pobj_parameter->ErrorCheck(psi->name,psi->pRealParmInfo,psi->RealParmNum,psi->RealSecondParmNum);
354
355 if(psi->dwType==SUBTYPE_MACRO){
356 //マクロ関数の場合は、パラメータ省略を考慮する
357 pobj_parameter->MacroParameterSupport(psi->pRealParmInfo);
358 }
359
360 //一時オブジェクトを生成
361 pobj_parameter->NewTempParameters( psi->name,psi->pRealParmInfo,psi->RealParmNum,psi->RealSecondParmNum );
362
363 //レジスタ、スタックフレームにセット
364 int ParmSize;
365 ParmSize=pobj_parameter->SetParameter(psi->name,psi->pRealParmInfo,psi->RealParmNum,psi->RealSecondParmNum);
366
367
368
369 if(psi->ReturnType==DEF_OBJECT){
370 //////////////////////////////////////////////////////
371 // 戻り値にオブジェクト インスタンスを持つ場合
372 // ※ByRef _System_ReturnObject パラメータをセット
373 //////////////////////////////////////////////////////
374
375 int object_size;
376 object_size=GetSizeOfClass(psi->u.Return_pobj_c);
377
378 //push object_size
379 op_push_value(object_size);
380
381 //call calloc
382 extern SUBINFO *pSub_calloc;
383 op_call(pSub_calloc);
384
385 //push eax
386 op_push(REG_EAX);
387 }
388
389
390 if(psi->pobj_ParentClass&&bStatic==0){
391 //////////////////////////////////////////////////////
392 // メンバ関数の場合
393 // ※_System_LocalThis パラメータをセット
394 //////////////////////////////////////////////////////
395
396 if(ObjectName[0]){
397 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
398 else{
399 RELATIVE_VAR RelativeVar;
400 if( pMethod->isConst ){
401 //Constアクセスが可能なメソッドの場合
402 if( !GetVarOffsetReadOnly( ObjectName, &i2, &RelativeVar, 0 ) ) return -1;
403 }
404 else{
405 //Constアクセスが不可能なメソッドの場合
406 if( !GetVarOffsetReadWrite( ObjectName, &i2, &RelativeVar, 0 ) ) return -1;
407 }
408
409 SetVarPtrToEax(&RelativeVar);
410
411 //参照タイプが整合しているかをチェック
412 if(i2!=RefType) SetError(104,ObjectName,cp);
413
414 if(i2==DEF_PTR_OBJECT){
415 //mov eax,dword ptr[eax]
416 OpBuffer[obp++]=(char)0x8B;
417 OpBuffer[obp++]=(char)0x00;
418 }
419
420 //mov ecx,eax
421 OpBuffer[obp++]=(char)0x8B;
422 OpBuffer[obp++]=(char)0xC8;
423 }
424 }
425 else{
426InClassMember:
427 if(dwFlags&PROCFLAG_NEW){
428 //New演算子によるコンストラクタ呼び出しの場合
429 //mov ecx,dword ptr[esp+ParmSize]
430 OpBuffer[obp++]=(char)0x8B;
431 OpBuffer[obp++]=(char)0x8C;
432 OpBuffer[obp++]=(char)0x24;
433 *((long *)(OpBuffer+obp))=ParmSize;
434 obp+=sizeof(long);
435 }
436 else{
437 //Thisポインタをecxにコピー
438 SetThisPtrToReg(REG_ECX);
439 }
440 }
441
442 //push ecx
443 op_push(REG_ECX);
444 }
445
446 if(psi->bVirtual){
447 //仮想関数(オブジェクトメソッド)呼び出し
448 //pObj->func_table->func1
449 // ->func2
450 // ->func3
451
452 //mov edx,dword ptr[ecx]
453 OpBuffer[obp++]=(char)0x8B;
454 OpBuffer[obp++]=(char)0x11;
455
456 for(i=0,i2=0;i<pobj_c->iMethodNum;i++){
457 if(pobj_c->ppobj_Method[i]->psi==psi) break;
458 if(pobj_c->ppobj_Method[i]->psi->bVirtual) i2++;
459 }
460
461 //call dword ptr[edx+func_index]
462 if(i2*PTR_SIZE<=0x7F){
463 OpBuffer[obp++]=(char)0xFF;
464 OpBuffer[obp++]=(char)0x52;
465 OpBuffer[obp++]=(char)(i2*PTR_SIZE);
466 }
467 else{
468 OpBuffer[obp++]=(char)0xFF;
469 OpBuffer[obp++]=(char)0x92;
470 *((long *)(OpBuffer+obp))=i2*PTR_SIZE;
471 obp+=sizeof(long);
472 }
473 }
474 else{
475 //通常呼び出し
476
477 //call ProcAddr
478 op_call(psi);
479 }
480
481 if(psi->bCdecl){
482 //add esp,ParmSize
483 op_add_esp(ParmSize);
484 }
485
486 //一時オブジェクトを破棄
487 pobj_parameter->DeleteTempParameters();
488
489 //パラメータオブジェクトを破棄
490 delete pobj_parameter;
491
492 if(plpIndex) *plpIndex=psi->u.ReturnIndex;
493
494 return psi->ReturnType;
495}
496
497int Opcode_CallDllProc(char *Parameter,DECLAREINFO *pdi,LONG_PTR *plpIndex){
498 char *temporary;
499
500 temporary=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter)+1);
501
502 extern BOOL bDebugCompile;
503 extern BOOL bDebugSupportProc;
504 if(bDebugCompile&&bDebugSupportProc==0&&lstrcmp(pdi->name,"DebugBreak")!=0)
505 Call_DebugSys_SaveContext();
506
507 pdi->bUse=1;
508
509
510 ////////////////////////
511 // パラメータのセット
512 ////////////////////////
513
514 //パラメータオブジェクトを生成
515 CParameter *pobj_parameter=0;
516 pobj_parameter=new CParameter(Parameter);
517
518 //エラーチェック
519 pobj_parameter->ErrorCheck(pdi->name,pdi->pParmInfo,pdi->ParmNum,pdi->ParmNum);
520
521 //レジスタ、スタックフレームにセット
522 int ParmSize;
523 ParmSize=pobj_parameter->SetParameter(pdi->name,pdi->pParmInfo,pdi->ParmNum,pdi->ParmNum);
524
525 //パラメータオブジェクトを破棄
526 delete pobj_parameter;
527
528
529 //動的リンクされたプロシージャの呼び出し
530
531 //call dword ptr[LookupTable]
532 OpBuffer[obp++]=(char)0xFF;
533 OpBuffer[obp++]=(char)0x15;
534 pobj_ImportAddrSchedule->add(pdi);
535 obp+=sizeof(long);
536
537 if(pdi->bCdecl){
538 //add esp,ParmSize
539 op_add_esp(ParmSize);
540 }
541
542 if(plpIndex) *plpIndex=pdi->u.ReturnIndex;
543
544 HeapDefaultFree(temporary);
545
546 return pdi->ReturnType;
547}
Note: See TracBrowser for help on using the repository browser.