source: dev/BasicCompiler64/Compile_CallProc.cpp@ 75

Last change on this file since 75 was 75, checked in by dai_9181, 18 years ago

TYPEINFO→Typeへのリファクタリングを実施。64bitはほぼ完了。32bitが全般的に未完成。

File size: 11.6 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 UserProc *pSub_System_GetEip;
11 op_call(pSub_System_GetEip);
12
13 //mov rdx,rax
14 op_mov_RR(REG_RDX,REG_RAX);
15
16 //mov rcx,rsp
17 op_mov_RR(REG_RCX,REG_RSP);
18
19 //call _DebugSys_SaveContext
20 extern UserProc *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}
32
33
34bool Opcode_CallProcPtr( const char *variable, const char *lpszParms,ProcPointer *pProcPointer){
35
36 extern BOOL bDebugCompile;
37 extern BOOL bDebugSupportProc;
38 if(bDebugCompile&&bDebugSupportProc==0)
39 Call_DebugSys_SaveContext();
40
41
42 ////////////////////////
43 // パラメータのセット
44 ////////////////////////
45
46 //パラメータオブジェクトを生成
47 ParamImpl *pobj_parameter=0;
48 pobj_parameter=new ParamImpl(lpszParms);
49
50 //エラーチェック
51 if( !pobj_parameter->ErrorCheck(variable,pProcPointer->Params() ) ){
52 //パラメータにエラーがあるときは処理を終える
53 return false;
54 }
55
56 //スタックフレームに存在する既存のパラメータをバックアップ
57 pobj_parameter->BackupParameter( (int)pProcPointer->Params().size() );
58
59 //一時オブジェクトを生成
60 pobj_parameter->NewTempParameters( variable,pProcPointer->Params() );
61
62 //レジスタ、スタックフレームにセット
63 pobj_parameter->SetParameter(variable,pProcPointer->Params() );
64
65
66
67 RELATIVE_VAR RelativeVar;
68 GetVarOffsetReadOnly(variable,&RelativeVar,Type());
69 SetVarPtrToReg(REG_RAX,&RelativeVar);
70
71 //mov rax,qword ptr[rax]
72 op_mov_RM(sizeof(_int64),REG_RAX,REG_RAX,0,MOD_BASE);
73
74 //call rax
75 OpBuffer[obp++]=(char)0xFF;
76 OpBuffer[obp++]=(char)0xD0;
77
78
79 //レジスタのブロッキングを解除 ※パラメータセット時にロックされたレジスタ
80 pobj_BlockReg->clear();
81
82 //一時オブジェクトを破棄
83 pobj_parameter->DeleteTempParameters();
84
85 //スタックフレームに存在する既存のパラメータを復元
86 pobj_parameter->RestoreParameter( (int)pProcPointer->Params().size() );
87
88 //パラメータオブジェクトを破棄
89 delete pobj_parameter;
90
91 return true;
92}
93
94bool Opcode_CallProc(const char *Parameter,UserProc *pUserProc,DWORD dwFlags,const char *ObjectName,int RefType){
95 int i2;
96
97 if( pUserProc->IsMacro() ){
98 if( lstrcmpi( pUserProc->GetName().c_str(), "Print" ) == 0 ){
99 Opcode_Print(Parameter,0);
100 return true;
101 }
102 if( lstrcmpi( pUserProc->GetName().c_str(), "Input" ) == 0 ){
103 Opcode_Input(Parameter);
104 return true;
105 }
106 if( lstrcmpi( pUserProc->GetName().c_str(), "Write" ) == 0 ){
107 Opcode_Print(Parameter,1);
108 return true;
109 }
110 }
111
112 pUserProc->Using();
113
114 bool isStatic = false;
115 const CClass *pobj_c = NULL;
116 CMethod *pMethod = NULL;
117 if( pUserProc->GetParentClassPtr() ){
118 //クラスのメンバ関数を呼び出す場合はアクセスチェックを行う
119 if(ObjectName[0]){
120 if(lstrcmpi(ObjectName,"Super")==0){
121 //クラスメンバ関数内から基底クラスの呼び出し
122 pobj_c=pobj_CompilingClass;
123 }
124 else{
125 //"->"によってオブジェクトを指定する通常のメンバ関数呼び出し
126 Type varType;
127 GetVarType( ObjectName, varType, false );
128 pobj_c = &varType.GetClass();
129 if( NATURAL_TYPE( varType.GetBasicType() ) != DEF_OBJECT ){
130 pobj_c=pobj_DBClass->check(ObjectName);
131 if( pobj_c ){
132 isStatic = true;
133 }
134 else{
135 SetError(300,NULL,cp);
136 }
137 }
138 }
139 }
140 else{
141 if(dwFlags&PROCFLAG_NEW){
142 //New演算子によるコンストラクタ呼び出し
143 pobj_c=pUserProc->GetParentClassPtr();
144 }
145 else{
146 //クラスメンバ関数内から同一クラスのメンバ関数の呼び出し
147 pobj_c=pobj_CompilingClass;
148 }
149 }
150
151
152 /////////////////////////////////
153 // メソッド情報を取得
154 /////////////////////////////////
155 pMethod = NULL;
156 if( ! isStatic ) pMethod = pobj_c->GetMethodInfo( pUserProc );
157 if( ! pMethod ){
158 //動的メソッドが取得できなかったときは静的メソッドを当たる
159 pMethod = pobj_c->GetStaticMethodInfo( pUserProc );
160 if( !pMethod ){
161 SetError(300,NULL,cp);
162 return false;
163 }
164
165 //静的メンバ
166 isStatic = true;
167 }
168
169
170 //////////////////////////////
171 // アクセスエラーチェック
172 //////////////////////////////
173 DWORD dwAccess = pMethod->dwAccess;
174
175 if(ObjectName[0]){
176 //外部からの呼び出し
177 if(pobj_c==pobj_CompilingClass){
178 //同一クラスオブジェクトの場合はプライベートアクセスを容認する
179 if(dwAccess==ACCESS_NON){
180 SetError(109,pUserProc->GetName(),cp);
181 return false;
182 }
183 }
184 else{
185 if(dwAccess==ACCESS_PRIVATE||
186 dwAccess==ACCESS_NON){
187 SetError(109,pUserProc->GetName(),cp);
188 return false;
189 }
190 if(dwAccess==ACCESS_PROTECTED){
191 SetError(110,pUserProc->GetName(),cp);
192 return false;
193 }
194 }
195 }
196 else{
197 //クラス内部からの呼び出し(継承によるACCESS_NONのみをエラーとする)
198 if(dwAccess==ACCESS_NON){
199 SetError(109,pUserProc->GetName(),cp);
200 return false;
201 }
202 }
203 }
204
205
206 ///////////////////////////////////////////////////////////////
207 // _System_LocalThisのダミーをセット
208 ///////////////////////////////////////////////////////////////
209
210 char temporary[VN_SIZE]={0};
211 if( pUserProc->GetParentClassPtr() && isStatic == false ){
212 //_System_LocalThis(第一パラメータ)のダミーを作成
213 lstrcpy(temporary,"0,");
214 }
215
216 if(Parameter[0]=='\0'&&temporary[0])
217 temporary[lstrlen(temporary)-1]=0;
218 else lstrcat(temporary,Parameter);
219
220
221 //パラメータセット前のspオフセットを取得(Newの場合はここにThisポインタが格納されている)
222 int this_sp_offset = pobj_sf->GetNowSp();
223
224
225 ////////////////////////
226 // パラメータをセット
227 ////////////////////////
228
229 //パラメータオブジェクトを生成
230 ParamImpl *pobj_parameter=0;
231 pobj_parameter=new ParamImpl(temporary);
232
233 //エラーチェック
234 if( !pobj_parameter->ErrorCheck(pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetSecondParmNum() ) ){
235 //パラメータにエラーがあるときは処理を終える
236 return false;
237 }
238
239 if(pUserProc->IsMacro()){
240 //マクロ関数の場合は、パラメータ省略を考慮する
241 pobj_parameter->MacroParameterSupport( pUserProc->RealParams() );
242 }
243
244 //スタックフレームに存在する既存のパラメータをバックアップ
245 pobj_parameter->BackupParameter( (int)pUserProc->RealParams().size() );
246
247 //一時オブジェクトを生成
248 pobj_parameter->NewTempParameters( pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetRealSecondParmNum() );
249
250 //レジスタ、スタックフレームにセット
251 pobj_parameter->SetParameter(pUserProc->GetName(),pUserProc->RealParams(),pUserProc->GetRealSecondParmNum() );
252
253 if(pUserProc->ReturnType().IsStruct() ){
254 //////////////////////////////////////////////////////
255 // 戻り値に構造体インスタンスを持つ場合
256 // ※ByRef _System_ReturnValue パラメータをセット
257 //////////////////////////////////////////////////////
258
259
260 //////////////////////////////////////////////////////
261 ///// レジスタ資源のバックアップ
262 { BACKUP_REGISTER_RESOURCE
263 //////////////////////////////////////////////////////
264
265 int object_size = pUserProc->ReturnType().GetClass().GetSize();
266
267 //mov rcx,object_size
268 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
269
270 //call calloc
271 extern UserProc *pSub_calloc;
272 op_call(pSub_calloc);
273
274 //mov r13,rax
275 op_mov_RR(REG_R13,REG_RAX);
276
277 /////////////////////////////////////////////
278 ////// レジスタ資源を復元
279 RESTORE_REGISTER_RESOURCE
280 }////////////////////////////////////////////
281
282 if( pUserProc->GetParentClassPtr() && isStatic == false ){
283 //mov rdx,r13
284 op_mov_RR(REG_RDX,REG_R13);
285 }
286 else{
287 //mov rcx,r13
288 op_mov_RR(REG_RCX,REG_R13);
289 }
290 }
291
292
293 if( pUserProc->GetParentClassPtr() && isStatic == false ){
294 ///////////////////////////////
295 // メンバ関数の場合
296 // thisポインタをrcxで受け渡す
297 ///////////////////////////////
298
299 if(ObjectName[0]){
300 if(lstrcmpi(ObjectName,"Super")==0) goto InClassMember;
301 else{
302 RELATIVE_VAR RelativeVar;
303 if( pMethod->isConst ){
304 //Constアクセスが可能なメソッドの場合
305 if( !GetVarOffsetReadOnly( ObjectName, &RelativeVar, Type() ) ){
306 return false;
307 }
308 }
309 else{
310 //Constアクセスが不可能なメソッドの場合
311 if( !GetVarOffsetReadWrite( ObjectName, &RelativeVar, Type() ) ){
312 return false;
313 }
314 }
315
316 SetVarPtrToReg(REG_RCX,&RelativeVar);
317
318 // 参照を実体ポインタにする
319 //mov rcx,qword ptr[rcx]
320 op_mov_RM(sizeof(_int64),REG_RCX,REG_RCX,0,MOD_BASE);
321 }
322 }
323 else{
324InClassMember:
325 if(dwFlags&PROCFLAG_NEW){
326 //New演算子によるコンストラクタ呼び出しの場合
327
328 //mov rcx,qword ptr[rsp+offset] ※スタックフレームを利用
329 pobj_sf->ref_offset_data(REG_RCX, this_sp_offset);
330 }
331 else{
332 //自身のオブジェクトのThisポインタをrcxにコピー
333 SetThisPtrToReg(REG_RCX);
334 }
335 }
336 }
337
338 if( pUserProc->IsVirtual() ){
339 //仮想関数(オブジェクトメソッド)呼び出し
340 //pObj->func_table->func1
341 // ->func2
342 // ->func3
343
344 //mov r11,qword ptr[rcx]
345 op_mov_RM(sizeof(_int64),REG_R11,REG_RCX,0,MOD_BASE);
346
347 i2 = pobj_c->GetFuncNumInVtbl( pUserProc );
348
349 //call qword ptr[r11+func_index]
350 if(i2*PTR_SIZE<=0x7F){
351 OpBuffer[obp++]=(char)0x41;
352 OpBuffer[obp++]=(char)0xFF;
353 OpBuffer[obp++]=(char)0x53;
354 OpBuffer[obp++]=(char)(i2*PTR_SIZE);
355 }
356 else{
357 OpBuffer[obp++]=(char)0x41;
358 OpBuffer[obp++]=(char)0xFF;
359 OpBuffer[obp++]=(char)0x93;
360 *((long *)(OpBuffer+obp))=i2*PTR_SIZE;
361 obp+=sizeof(long);
362 }
363 }
364 else{
365 //通常呼び出し
366
367 //call ProcAddr
368 op_call(pUserProc);
369 }
370
371 /* 64コンパイラでは不要
372 if(pDllProc->bCdecl){
373 //add esp,ParmSize
374 }*/
375
376
377 //レジスタのブロッキングを解除 ※パラメータセット時にロックされたレジスタ
378 pobj_BlockReg->clear();
379
380 //一時オブジェクトを破棄
381 pobj_parameter->DeleteTempParameters();
382
383 //スタックフレームに存在する既存のパラメータを復元
384 pobj_parameter->RestoreParameter( (int)pUserProc->RealParams().size() );
385
386 //パラメータオブジェクトを破棄
387 delete pobj_parameter;
388
389 return true;
390}
391
392bool Opcode_CallDllProc( const char *lpszParms, DllProc *pDllProc ){
393
394 extern BOOL bDebugCompile;
395 extern BOOL bDebugSupportProc;
396 if(bDebugCompile&&bDebugSupportProc==0&& pDllProc->GetName() != "DebugBreak" ){
397 Call_DebugSys_SaveContext();
398 }
399
400
401 ////////////////////////
402 // パラメータのセット
403 ////////////////////////
404
405 //パラメータオブジェクトを生成
406 ParamImpl *pobj_parameter=0;
407 pobj_parameter=new ParamImpl(lpszParms);
408
409 //エラーチェック
410 if( !pobj_parameter->ErrorCheck( pDllProc->GetName(), pDllProc->Params() ) ){
411 //パラメータにエラーがあるときは処理を終える
412 return false;
413 }
414
415 //スタックフレームに存在する既存のパラメータをバックアップ
416 pobj_parameter->BackupParameter( (int)pDllProc->Params().size() );
417
418 //一時オブジェクトを生成
419 pobj_parameter->NewTempParameters( pDllProc->GetName(), pDllProc->Params() );
420
421 //レジスタ、スタックフレームにセット
422 pobj_parameter->SetParameter(pDllProc->GetName(), pDllProc->Params() );
423
424
425 //レジスタのブロッキングを解除 ※パラメータセット時にロックされたレジスタ
426 pobj_BlockReg->clear();
427
428
429 //動的リンクされたプロシージャの呼び出し
430
431 //call dword ptr[ImportTable]
432 op_call( pDllProc );
433
434 /* 64コンパイラでは不要
435 if(pDllProc->bCdecl){
436 //add esp,ParmSize
437 }*/
438
439 //一時オブジェクトを破棄
440 pobj_parameter->DeleteTempParameters();
441
442 //スタックフレームに存在する既存のパラメータを復元
443 pobj_parameter->RestoreParameter( (int)pDllProc->Params().size() );
444
445 //パラメータオブジェクトを破棄
446 delete pobj_parameter;
447
448 return true;
449}
Note: See TracBrowser for help on using the repository browser.