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

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