source: dev/BasicCompiler64/CParameter.cpp@ 60

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

派生クラスから基底クラスへのインスタンスコピーまたは参照を可能にした

File size: 13.3 KB
Line 
1#include "../BasicCompiler_Common/common.h"
2#include "opcode.h"
3
4void CParameter::NewTempParameters( const char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum ){
5 ///////////////////////////////////////////////////////
6 // 一時オブジェクトをあらかじめスタックに積んでおく
7 ///////////////////////////////////////////////////////
8
9 useTempObject = false;
10
11 BOOL bEllipse;
12 if(pi_num){
13 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
14 else bEllipse=0;
15 }
16 else bEllipse=0;
17
18 for(int i2=ParmsNum-1;i2>=0;i2--){
19 useTempParameters[i2] = false;
20
21 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
22
23 if(i2==0&&ppi[i2].name){
24 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
25 //オブジェクトメンバの第一パラメータのThisポインタ
26 continue;
27 }
28 }
29 if((i2==0||i2==1)&&ppi[i2].name){
30 if(lstrcmp(ppi[i2].name,FuncName)==0){
31 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
32 continue;
33 }
34 }
35
36 TYPEINFO DummyTypeInfo;
37 BOOL bByVal;
38 if(bEllipse){
39 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
40 bByVal=1;
41 }
42 else{
43 DummyTypeInfo.type=ppi[i2].type;
44 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
45 bByVal=ppi[i2].bByVal;
46 }
47
48
49 if( !bByVal ){
50 //ポインタ参照
51 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
52 //ポインタ指定
53 continue;
54 }
55
56 LONG_PTR lpVarIndex;
57 if( GetVarType( Parms[i2], &lpVarIndex, FALSE ) == -1 ){
58 //変数ではないとき
59 int reg = REG_RAX;
60 int type = NumOpe( &reg, Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
61
62 //スタックフレームへコピー
63 StackOffsetOfTempObject[i2] = pobj_sf->push(reg);
64
65 bool result = CheckDifferentType(
66 DummyTypeInfo.type,
67 DummyTypeInfo.u.lpIndex,
68 type,
69 lpVarIndex,
70 FuncName,
71 i2);
72
73 if( result ){
74 useTempParameters[i2] = true;
75 useTempObject = true;
76
77 types[i2].type = type;
78 types[i2].u.lpIndex = lpVarIndex;
79 }
80 }
81 }
82 }
83}
84void CParameter::DeleteTempParameters(){
85 ///////////////////////////////////////////////////////
86 // 一時オブジェクトを破棄
87 ///////////////////////////////////////////////////////
88 if( !useTempObject ) return;
89
90 for(int i2=ParmsNum-1;i2>=0;i2--){
91 if( useTempParameters[i2] ){
92 //スタックフレームから取得
93 pobj_sf->ref(REG_RCX);
94
95 //デストラクタを呼び出す
96
97 //call destructor
98 CMethod *method = types[i2].u.pobj_Class->GetDestructorMethod();
99 if( method ){
100 op_call( method->psi );
101 }
102
103 //メモリを解放する
104
105 pobj_sf->pop(REG_RCX);
106
107 //call free
108 extern SUBINFO *pSub_free;
109 op_call(pSub_free);
110 }
111 }
112}
113
114void CParameter::SetObjectParameter(int reg,CClass *pobj_Class,LPSTR Parameter){
115 //////////////////////////////////////////////////////
116 ///// レジスタ資源のバックアップ
117 { BACKUP_REGISTER_RESOURCE
118 //////////////////////////////////////////////////////
119
120 int object_size;
121 object_size=GetSizeOfClass(pobj_Class);
122
123 //mov rcx,object_size
124 op_mov_RV(sizeof(_int64),REG_RCX,object_size);
125
126 //call calloc
127 extern SUBINFO *pSub_calloc;
128 op_call(pSub_calloc);
129
130 //mov r11,rax
131 op_mov_RR(REG_R11,REG_RAX);
132
133 //mov qword ptr[rsp+offset],r11 ※スタックフレームを利用
134 pobj_sf->push(REG_R11);
135
136 TYPEINFO BaseType={DEF_OBJECT,(LONG_PTR)pobj_Class};
137 TYPEINFO CalcType;
138 CalcType.type=NumOpe_GetType(Parameter,&BaseType,&CalcType.u.lpIndex);
139
140 if( pobj_Class->GetCopyConstructorMethod()
141 && CalcType.type==DEF_OBJECT&&CalcType.u.pobj_Class==pobj_Class){
142 ////////////////////////////////////
143 // コピーコンストラクタを呼び出す
144 ////////////////////////////////////
145
146 BOOL bUseHeap;
147 int temp_reg=REG_RDX;
148 CalcType.type=NumOpe(&temp_reg,Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
149
150 if(bUseHeap){
151 //mov r14,rdx
152 op_mov_RR(REG_R14,REG_RDX);
153 }
154
155 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
156 pobj_sf->ref(REG_R11);
157
158 //mov rcx,this
159 op_mov_RR(REG_RCX,REG_R11);
160
161 //call constructor
162 op_call(pobj_Class->GetCopyConstructorMethod()->psi);
163
164
165 if(bUseHeap){
166 FreeTempObject(REG_R14,pobj_Class);
167 }
168 }
169 else{
170 if( pobj_Class->GetConstructorMethod() ){
171 ////////////////////////////////
172 // コンストラクタを呼び出す
173 ////////////////////////////////
174
175 //mov rcx,this
176 op_mov_RR(REG_RCX,REG_R11);
177
178 //call constructor
179 op_call(pobj_Class->GetConstructorMethod()->psi);
180 }
181
182
183 BOOL bUseHeap;
184 int temp_reg=REG_RAX;
185 CalcType.type=NumOpe(&temp_reg,Parameter,DEF_OBJECT,(LONG_PTR)pobj_Class,&CalcType.u.lpIndex,&bUseHeap);
186
187
188 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
189 pobj_sf->ref(REG_R11);
190
191
192 RELATIVE_VAR RelativeVar;
193 RelativeVar.bOffsetOffset=0;
194 RelativeVar.offset=0;
195 RelativeVar.dwKind=VAR_DIRECTMEM;
196
197 SetObjectVariableFromRax((LONG_PTR)pobj_Class,CalcType.type,CalcType.u.lpIndex,&RelativeVar,bUseHeap);
198
199 }
200
201 //mov r11,qword ptr[rsp+offset] ※スタックフレームを利用
202 pobj_sf->pop(REG_R11);
203
204 /////////////////////////////////////////////
205 ////// レジスタ資源を復元
206 RESTORE_REGISTER_RESOURCE
207 }////////////////////////////////////////////
208
209 //mov reg,r11
210 op_mov_RR(reg,REG_R11);
211}
212
213void CParameter::SetParameter(const char *FuncName,PARAMETER_INFO *ppi,int pi_num,int SecondParmNum){
214 ///////////////////////////////////////////////////////////
215 // パラメータをレジスタ及びスタックフレームにセット
216 ///////////////////////////////////////////////////////////
217 int i2,i3;
218
219 BOOL bEllipse;
220 if(pi_num){
221 if(ppi[pi_num-1].type==DEF_ELLIPSE) bEllipse=1;
222 else bEllipse=0;
223 }
224 else bEllipse=0;
225
226 BOOL bHas_System_LocalThis=0;
227 if(ParmsNum>=1){
228 if(lstrcmp(ppi[0].name,"_System_LocalThis")==0)
229 bHas_System_LocalThis=1;
230 }
231
232 //戻り値用の変数名を取得
233 const char *lpszVarNameToReturn = (FuncName[0]==1&&FuncName[1]==ESC_OPERATOR)?"_System_ReturnValue":FuncName;
234
235 //パラメータをレジスタとスタックに格納
236 int CalcType;
237 LONG_PTR lpCalcIndex;
238 BOOL bCalcUseHeap;
239 int ParmSize=0;
240 int reg,temp_reg;
241 RELATIVE_VAR RelativeVar;
242 for(i2=ParmsNum-1;i2>=0;i2--){
243 if(bEllipse&&i2<=pi_num-2) bEllipse=0;
244
245 if(i2==0&&ppi[i2].name){
246 if(lstrcmp(ppi[i2].name,"_System_LocalThis")==0){
247 //オブジェクトメンバの第一パラメータのThisポインタ
248 continue;
249 }
250 }
251 if((i2==0||i2==1)&&ppi[i2].name){
252 if(lstrcmp(ppi[i2].name,lpszVarNameToReturn)==0){
253 //オブジェクトメンバの第一または第二パラメータの戻り値用オブジェクト
254 continue;
255 }
256 }
257
258 TYPEINFO DummyTypeInfo;
259 BOOL bByVal;
260 if(bEllipse){
261 DummyTypeInfo.type=NumOpe_GetType(Parms[i2],NULL,&DummyTypeInfo.u.lpIndex);
262 bByVal=1;
263 }
264 else{
265 DummyTypeInfo.type=ppi[i2].type;
266 DummyTypeInfo.u.lpIndex=ppi[i2].u.index;
267 bByVal=ppi[i2].bByVal;
268 }
269
270 int xmm_temp_sw=0;
271 if(IsRealNumberType(DummyTypeInfo.type)&&bByVal){
272 //実数型
273 if(i2==0) reg=REG_XMM0;
274 else if(i2==1) reg=REG_XMM1;
275 else if(i2==2) reg=REG_XMM2;
276 else if(i2==3) reg=REG_XMM3;
277 else{
278 reg=REG_XMM0;
279 xmm_temp_sw=1;
280 }
281 }
282 else{
283 //整数型
284 if(i2==0) reg=REG_RCX;
285 else if(i2==1) reg=REG_RDX;
286 else if(i2==2) reg=REG_R8;
287 else if(i2==3) reg=REG_R9;
288 else reg=REG_RAX;
289 }
290
291 if(bByVal==1){
292 //値参照
293
294 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
295 char temp2[255];
296 sprintf(temp2,"%s関数の第%dパラメータ",FuncName,i2+1);
297 SetError(19,temp2,cp);
298 continue;
299 }
300
301 if(DummyTypeInfo.type==DEF_OBJECT){
302 SetObjectParameter(reg,DummyTypeInfo.u.pobj_Class,Parms[i2]);
303 goto next;
304 }
305
306 temp_reg=reg;
307
308 extern LONG_PTR ProcPtr_BaseIndex;
309 LONG_PTR back_ProcPtr_BaseIndex;
310 back_ProcPtr_BaseIndex=ProcPtr_BaseIndex;
311 if(DummyTypeInfo.type==DEF_PTR_PROC) ProcPtr_BaseIndex=DummyTypeInfo.u.lpIndex;
312 else ProcPtr_BaseIndex=-1;
313
314 CalcType=NumOpe(&temp_reg,Parms[i2],DummyTypeInfo.type,DummyTypeInfo.u.lpIndex,&lpCalcIndex,&bCalcUseHeap);
315
316 ProcPtr_BaseIndex=back_ProcPtr_BaseIndex;
317
318 if(CalcType==-1) break;
319
320 if(CalcType==DEF_OBJECT){
321 //キャスト演算子のオーバーロードに対応する
322 CallCastOperatorProc(reg,CalcType,lpCalcIndex,bCalcUseHeap,DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
323 }
324
325
326 if(bEllipse){
327 if(IsRealNumberType(CalcType)){
328 //整数レジスタへコピー
329 //※cdeclの拡張パラメータは実数の場合も汎用レジスタで引渡し
330
331 if(0<=i2&&i2<=3){
332 if(i2==0) reg=REG_RCX;
333 else if(i2==1) reg=REG_RDX;
334 else if(i2==2) reg=REG_R8;
335 else if(i2==3) reg=REG_R9;
336
337 //movd reg,temp_reg
338 op_movd_RX(reg,temp_reg);
339 }
340 }
341 else if(IsWholeNumberType(CalcType)){
342 //整数型の場合は、64ビットへ拡張する
343 ExtendTypeTo64(CalcType,temp_reg);
344 }
345 }
346 else{
347 //型チェック
348 // TODO: _System_ReturnValueが考慮されていない?
349 if(bHas_System_LocalThis) i3=i2-1;
350 else i3=i2;
351 CheckDifferentType(
352 DummyTypeInfo.type,
353 DummyTypeInfo.u.lpIndex,
354 CalcType,
355 lpCalcIndex,
356 FuncName,
357 i3);
358
359
360 if(DummyTypeInfo.type==DEF_DOUBLE){
361 //Double型へ変換
362 ChangeTypeToXmm_Double(CalcType,reg,temp_reg);
363 }
364 else if(DummyTypeInfo.type==DEF_SINGLE){
365 //Single型へ変換
366 ChangeTypeToXmm_Single(CalcType,reg,temp_reg);
367 }
368 else if(IsWholeNumberType(DummyTypeInfo.type)){
369 //実数型 → 整数型
370 ChangeTypeToWhole(CalcType,DummyTypeInfo.type,reg,temp_reg);
371 }
372 }
373 }
374 else{
375 //ポインタ参照
376 if(Parms[i2][0]==1&&Parms[i2][1]==ESC_BYVAL){
377 //ポインタ指定
378
379 temp_reg=reg;
380 CalcType=NumOpe(&temp_reg,Parms[i2]+2,0,0,&lpCalcIndex);
381 if(CalcType==-1) break;
382
383 int ptr_type;
384 ptr_type=GetPtrType(DummyTypeInfo.type,DummyTypeInfo.u.lpIndex);
385
386 //型チェック
387 if(bHas_System_LocalThis) i3=i2-1;
388 else i3=i2;
389 CheckDifferentType(
390 ptr_type,
391 DummyTypeInfo.u.lpIndex,
392 CalcType,
393 lpCalcIndex,
394 FuncName,
395 i3);
396
397 if(IsRealNumberType(CalcType)){
398 //実数型 → 整数型
399 ChangeTypeToWhole(CalcType,DEF_QWORD,reg,temp_reg);
400 }
401 }
402 else{
403 //変数のアドレスを取得
404 int VarType;
405 LONG_PTR lpVarIndex;
406 if(GetVarOffset(
407 false,
408 false,
409 Parms[i2],
410 &VarType,
411 &RelativeVar,
412 &lpVarIndex)){
413
414 if(DummyTypeInfo.type!=DEF_ANY){
415 //型チェックを行う
416 if(DummyTypeInfo.type==VarType){
417 if(DummyTypeInfo.type==DEF_OBJECT){
418 if( !DummyTypeInfo.u.pobj_Class->IsEqualsOrSubClass( (CClass *)lpVarIndex ) ){
419 SetError(11,Parms[i2],cp);
420 }
421 }
422 }
423 else if((VarType&FLAG_PTR)&&((VarType^FLAG_PTR)==DummyTypeInfo.type)){
424 //仮引数がポインタ参照で、実引数が配列の先頭ポインタのとき
425 }
426 else{
427 SetError(11,Parms[i2],cp);
428 }
429 }
430
431 //変数アドレスをレジスタにセット
432 SetVarPtrToReg(reg,&RelativeVar);
433
434 }
435 else{
436 //一時オブジェクトをコピー
437
438 //mov reg, qword ptr[rsp+offset]
439 pobj_sf->ref_offset_data( reg, StackOffsetOfTempObject[i2] );
440
441 //VarType = NumOpe( &reg, Parms[i2], DummyTypeInfo.type, DummyTypeInfo.u.lpIndex, &lpVarIndex );
442 }
443 }
444 }
445next:
446 if(reg==REG_RAX){
447 //スタックフレームへコピー
448 //mov qword ptr[rsp+offset],rax
449 op_mov_MR(sizeof(_int64),REG_RAX,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
450 }
451 else if(xmm_temp_sw){
452 //スタックフレームへコピー
453
454 //movlpd qword ptr[rsp+offset],xmm0
455 op_movlpd_MR(REG_XMM0,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
456 }
457
458
459 /////////////////////
460 // レジスタをロック
461 /////////////////////
462
463 if(0<=i2&&i2<=3){
464 // ※rcx, rdx, r8, r9の場合のみ
465 pobj_BlockReg->lock(reg);
466 }
467 }
468
469 //パラメータが収まるだけのスタックフレームを確保
470 pobj_sf->parameter_allocate(pi_num*sizeof(_int64)+ sizeof(_int64)/*ret用*/ );
471}
472void CParameter::BackupParameter(int pi_num){
473 ///////////////////////////////////////////////////////////
474 // スタックフレームに存在する既存のパラメータをバックアップ
475 ///////////////////////////////////////////////////////////
476 int i2;
477
478 for(i2=0;i2<ParmsNum;i2++){
479 /////////////////////
480 // バックアップ
481 /////////////////////
482
483 extern CDBLockParms obj_DBLockParms;
484 if(obj_DBLockParms.array_LevelCount[i2]){
485 //mov r14,qword ptr[rsp+offset]
486 op_mov_RM(sizeof(_int64),REG_R14,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
487
488 //mov qword ptr[rsp+offset],r14 ※スタックフレームを利用
489 pobj_sf->push(REG_R14);
490 }
491
492 if(3<i2){
493 //スタックフレームをロック
494 extern CDBLockParms obj_DBLockParms;
495 obj_DBLockParms.lock(i2);
496 }
497 }
498}
499void CParameter::RestoreParameter(int pi_num){
500 ///////////////////////////////////////////////////////////
501 // スタックフレームに存在する既存のパラメータを復元
502 ///////////////////////////////////////////////////////////
503 int i2;
504
505 for(i2=ParmsNum-1;i2>=0;i2--){
506 /////////////////////
507 // 復元
508 /////////////////////
509
510 if(3<i2){
511 //スタックフレームをアンロック
512 extern CDBLockParms obj_DBLockParms;
513 obj_DBLockParms.unlock(i2);
514 }
515
516 extern CDBLockParms obj_DBLockParms;
517 if(obj_DBLockParms.array_LevelCount[i2]){
518 //mov r14,qword ptr[rsp+offset] ※スタックフレームを利用
519 pobj_sf->pop(REG_R14);
520
521 //mov qword ptr[rsp+offset],r14
522 op_mov_MR(sizeof(_int64),REG_R14,REG_RSP,i2*sizeof(_int64),MOD_BASE_DISP32);
523 }
524 }
525}
Note: See TracBrowser for help on using the repository browser.