source: dev/BasicCompiler32/Compile_CallProc.cpp@ 3

Last change on this file since 3 was 3, checked in by dai_9181, 17 years ago
File size: 12.0 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->SetParameter(variable,pi->pParmInfo,pi->ParmNum,pi->ParmNum);
180
181 //パラメータオブジェクトを破棄
182 delete pobj_parameter;
183
184
185 RELATIVE_VAR RelativeVar;
186 LONG_PTR lp;
187 GetVarOffset(1,variable,&i,&RelativeVar,&lp);
188 SetVarPtrToEax(&RelativeVar);
189
190 //mov eax,dword ptr[eax]
191 OpBuffer[obp++]=(char)0x8B;
192 OpBuffer[obp++]=(char)0x00;
193
194 //call eax
195 OpBuffer[obp++]=(char)0xFF;
196 OpBuffer[obp++]=(char)0xD0;
197
198 if(plpIndex) *plpIndex=pi->u.ReturnIndex;
199
200 return pi->ReturnType;
201}
202
203int Opcode_CallProc(char *Parameter,SUBINFO *psi,LONG_PTR *plpIndex,DWORD dwFlags,char *ObjectName,int RefType){
204 int i,i2;
205
206 if(psi->dwType==SUBTYPE_MACRO){
207 if(lstrcmpi(psi->name,"Print")==0){
208 Opcode_Print(Parameter,0);
209 return -1;
210 }
211 if(lstrcmpi(psi->name,"Input")==0){
212 Opcode_Input(Parameter);
213 return -1;
214 }
215 if(lstrcmpi(psi->name,"Write")==0){
216 Opcode_Print(Parameter,1);
217 return -1;
218 }
219 }
220
221 psi->bUse=1;
222
223 BOOL bStatic=0;
224 CClass *pobj_c;
225 if(psi->pobj_ParentClass){
226 //クラスのメンバ関数を呼び出す場合はアクセスチェックを行う
227 if(ObjectName[0]){
228 if(lstrcmpi(ObjectName,"Super")==0){
229 //クラスメンバ関数内からスーパークラスの呼び出し
230 pobj_c=pobj_CompilingClass;
231 }
232 else{
233 pobj_c=pobj_DBClass->check(ObjectName);
234 if(pobj_c){
235 //静的メンバ
236 bStatic=1;
237 }
238 else{
239 //"->"によってオブジェクトを指定する通常のメンバ関数呼び出し
240 GetVarType(ObjectName,(LONG_PTR *)&pobj_c,1);
241 }
242 }
243 }
244 else{
245 if(dwFlags&PROCFLAG_NEW){
246 //New演算子によるコンストラクタ呼び出し
247 pobj_c=psi->pobj_ParentClass;
248 }
249 else{
250 //クラスメンバ関数内から同一クラスのメンバ関数の呼び出し
251 pobj_c=pobj_CompilingClass;
252 }
253 }
254
255
256 DWORD dwAccess;
257 for(i=0;i<pobj_c->iMethodNum;i++){
258 if(psi==pobj_c->ppobj_Method[i]->psi) break;
259 }
260 if(i==pobj_c->iMethodNum){
261 for(i=0;i<pobj_c->iStaticMethodNum;i++){
262 if(psi==pobj_c->ppobj_StaticMethod[i]->psi) break;
263 }
264 dwAccess=pobj_c->ppobj_StaticMethod[i]->dwAccess;
265
266 bStatic=1;
267 }
268 else dwAccess=pobj_c->ppobj_Method[i]->dwAccess;
269
270
271 //////////////////////////////
272 // アクセスエラーチェック
273 //////////////////////////////
274
275 if(ObjectName[0]){
276 //外部からの呼び出し
277 if(pobj_c==pobj_CompilingClass){
278 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
279 if(dwAccess==ACCESS_NON){
280 SetError(109,psi->name,cp);
281 return -1;
282 }
283 }
284 else{
285 if(dwAccess==ACCESS_PRIVATE||
286 dwAccess==ACCESS_NON){
287 SetError(109,psi->name,cp);
288 return -1;
289 }
290 if(dwAccess==ACCESS_PROTECTED){
291 SetError(110,psi->name,cp);
292 return -1;
293 }
294 }
295 }
296 else{
297 //クラス内部からの呼び出し(継承によるACCESS_NONのみをエラーとする)
298 if(dwAccess==ACCESS_NON){
299 SetError(109,psi->name,cp);
300 return -1;
301 }
302 }
303 }
304
305
306
307 ///////////////////////////////////////////////////////////////
308 // _System_LocalThis、_System_ReturnObjectのダミーをセット
309 ///////////////////////////////////////////////////////////////
310
311 char temporary[VN_SIZE]={0};
312 if(psi->pobj_ParentClass&&bStatic==0){
313 //_System_LocalThis(第一パラメータ)のダミーを作成
314 lstrcpy(temporary,"0,");
315 }
316
317 if(psi->ReturnType==DEF_OBJECT){
318 //_System_ReturnObject(第一または第二パラメータのダミーを作成)
319 sprintf(temporary+lstrlen(temporary),"%c%c0,",1,ESC_BYVAL);
320 }
321
322 if(Parameter[0]=='\0'&&temporary[0])
323 temporary[lstrlen(temporary)-1]=0;
324 else lstrcat(temporary,Parameter);
325
326
327
328 ////////////////////////
329 // パラメータをセット
330 ////////////////////////
331
332 //パラメータオブジェクトを生成
333 CParameter *pobj_parameter=0;
334 pobj_parameter=new CParameter(temporary);
335
336 //エラーチェック
337 pobj_parameter->ErrorCheck(psi->name,psi->pRealParmInfo,psi->RealParmNum,psi->RealSecondParmNum);
338
339 if(psi->dwType==SUBTYPE_MACRO){
340 //マクロ関数の場合は、パラメータ省略を考慮する
341 pobj_parameter->MacroParameterSupport(psi->pRealParmInfo);
342 }
343
344 //レジスタ、スタックフレームにセット
345 int ParmSize;
346 ParmSize=pobj_parameter->SetParameter(psi->name,psi->pRealParmInfo,psi->RealParmNum,psi->RealSecondParmNum);
347
348 //パラメータオブジェクトを破棄
349 delete pobj_parameter;
350
351
352
353 if(psi->ReturnType==DEF_OBJECT){
354 //////////////////////////////////////////////////////
355 // 戻り値にオブジェクト インスタンスを持つ場合
356 // ※ByRef _System_ReturnObject パラメータをセット
357 //////////////////////////////////////////////////////
358
359 int object_size;
360 object_size=GetSizeOfClass(psi->u.Return_pobj_c);
361
362 //push object_size
363 op_push_value(object_size);
364
365 //call calloc
366 extern SUBINFO *pSub_calloc;
367 op_call(pSub_calloc);
368
369 //push eax
370 op_push(REG_EAX);
371 }
372
373
374 if(psi->pobj_ParentClass&&bStatic==0){
375 //////////////////////////////////////////////////////
376 // メンバ関数の場合
377 // ※_System_LocalThis パラメータをセット
378 //////////////////////////////////////////////////////
379
380 if(ObjectName[0]){
381 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
382
383 RELATIVE_VAR RelativeVar;
384 if(!GetVarOffset(1,ObjectName,&i2,&RelativeVar,0)) return -1;
385 SetVarPtrToEax(&RelativeVar);
386
387 //参照タイプが整合しているかをチェック
388 if(i2!=RefType) SetError(104,ObjectName,cp);
389
390 if(i2==DEF_PTR_OBJECT){
391 //mov eax,dword ptr[eax]
392 OpBuffer[obp++]=(char)0x8B;
393 OpBuffer[obp++]=(char)0x00;
394 }
395
396 //mov ecx,eax
397 OpBuffer[obp++]=(char)0x8B;
398 OpBuffer[obp++]=(char)0xC8;
399 }
400 else{
401InClassMember:
402 if(dwFlags&PROCFLAG_NEW){
403 //New演算子によるコンストラクタ呼び出しの場合
404 //mov ecx,dword ptr[esp+ParmSize]
405 OpBuffer[obp++]=(char)0x8B;
406 OpBuffer[obp++]=(char)0x8C;
407 OpBuffer[obp++]=(char)0x24;
408 *((long *)(OpBuffer+obp))=ParmSize;
409 obp+=sizeof(long);
410 }
411 else{
412 //Thisポインタをecxにコピー
413 SetThisPtrToReg(REG_ECX);
414 }
415 }
416
417 //push ecx
418 op_push(REG_ECX);
419 }
420
421 if(psi->bVirtual){
422 //仮想関数(オブジェクトメソッド)呼び出し
423 //pObj->func_table->func1
424 // ->func2
425 // ->func3
426
427 //mov edx,dword ptr[ecx]
428 OpBuffer[obp++]=(char)0x8B;
429 OpBuffer[obp++]=(char)0x11;
430
431 for(i=0,i2=0;i<pobj_c->iMethodNum;i++){
432 if(pobj_c->ppobj_Method[i]->psi==psi) break;
433 if(pobj_c->ppobj_Method[i]->psi->bVirtual) i2++;
434 }
435
436 //call dword ptr[edx+func_index]
437 if(i2*PTR_SIZE<=0x7F){
438 OpBuffer[obp++]=(char)0xFF;
439 OpBuffer[obp++]=(char)0x52;
440 OpBuffer[obp++]=(char)(i2*PTR_SIZE);
441 }
442 else{
443 OpBuffer[obp++]=(char)0xFF;
444 OpBuffer[obp++]=(char)0x92;
445 *((long *)(OpBuffer+obp))=i2*PTR_SIZE;
446 obp+=sizeof(long);
447 }
448 }
449 else{
450 //通常呼び出し
451
452 //call ProcAddr
453 op_call(psi);
454 }
455
456 if(psi->bCdecl){
457 //add esp,ParmSize
458 op_add_esp(ParmSize);
459 }
460
461 if(plpIndex) *plpIndex=psi->u.ReturnIndex;
462
463 return psi->ReturnType;
464}
465
466int Opcode_CallDllProc(char *Parameter,DECLAREINFO *pdi,LONG_PTR *plpIndex){
467 char *temporary;
468
469 temporary=(char *)HeapAlloc(hHeap,0,lstrlen(Parameter)+1);
470
471 extern BOOL bDebugCompile;
472 extern BOOL bDebugSupportProc;
473 if(bDebugCompile&&bDebugSupportProc==0&&lstrcmp(pdi->name,"DebugBreak")!=0)
474 Call_DebugSys_SaveContext();
475
476 pdi->bUse=1;
477
478
479 ////////////////////////
480 // パラメータのセット
481 ////////////////////////
482
483 //パラメータオブジェクトを生成
484 CParameter *pobj_parameter=0;
485 pobj_parameter=new CParameter(Parameter);
486
487 //エラーチェック
488 pobj_parameter->ErrorCheck(pdi->name,pdi->pParmInfo,pdi->ParmNum,pdi->ParmNum);
489
490 //レジスタ、スタックフレームにセット
491 int ParmSize;
492 ParmSize=pobj_parameter->SetParameter(pdi->name,pdi->pParmInfo,pdi->ParmNum,pdi->ParmNum);
493
494 //パラメータオブジェクトを破棄
495 delete pobj_parameter;
496
497
498 //動的リンクされたプロシージャの呼び出し
499
500 //call dword ptr[LookupTable]
501 OpBuffer[obp++]=(char)0xFF;
502 OpBuffer[obp++]=(char)0x15;
503 pobj_ImportAddrSchedule->add(pdi);
504 obp+=sizeof(long);
505
506 if(pdi->bCdecl){
507 //add esp,ParmSize
508 op_add_esp(ParmSize);
509 }
510
511 if(plpIndex) *plpIndex=pdi->u.ReturnIndex;
512
513 HeapDefaultFree(temporary);
514
515 return pdi->ReturnType;
516}
Note: See TracBrowser for help on using the repository browser.