source: dev/BasicCompiler64/Compile_CallProc.cpp@ 75

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

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

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