source: dev/BasicCompiler64/Compile_CallProc.cpp@ 137

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