source: dev/trunk/abdev/BasicCompiler64/Compile_CallProc.cpp@ 198

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